While we don't have some significant parts of WCF 3.0 stack such as working message security, we have some new stuff, like WebHttpBinding I explained on Day 9. It also applies to WCF 4.0. We have new routing stack.
WCF router support is only in SVN trunk, in System.ServiceModel.Routing assembly, mostly in System.ServiceModel.Routing namespace. Note that .NET 4.0 is still in beta, so things may change as .NET 4 development goes on.
Message router is to dispatch messages that it received from clients, to certain servers. A WCF router is a WCF service for router client users, while the router works as a WCF client for routed services (which may not be WCF).
Routing design is almost simple: a WCF router service has a table of a message filter that is used to test if a message matches it or not, and a set of endpoints to dispatch messages it received. The table is represented as MessageFilterTable<MessageFilter,IEnumerable<ServiceEndpoint>>.
(Usually just one service endpoint is enough; simplex or duplex channels may dispatch messages to more than one service endpoints.)
Message router often has to rebuild the input message, like, adjusting message versions and To message header.
I haven't prepared an entire routing example (I tested it with MS sample in 4.0), but router usage would look like:
var host = new ServiceHost (typeof (RoutingService)); host.AddServiceEndpoint ( typeof (IRequestReplyRouter), new BasicHttpBinding (), new Uri ("http://localhost:8081/router")); var config = new RoutingConfiguration (); var clientEndpoint = new ServiceEndpoint ( ContractDescription.GetContract (typeof (IRequestReplyRouter)), new BasicHttpBinding (), new EndpointAddress ("http://localhost:8080/service")); var list = new List<ServiceEndpoint> (); list.Add (clientEndpoint); config.FilterTable.Add (new MatchAllMessageFilter (), list); host.Description.Behaviors.Add (new RoutingBehavior (config));
There is not many things to explain for WCF routing, so I'd explain its internals instead so that some people might want to write similar code for several purposes.
To host a routing service, RoutingService is used. It has four interfaces for several channel interface types;
- IRequestReplyRouter for typical request-reply channels
- ISimplexDatagramRouter for input/output channels
- ISimplexSessionRouter for input/output sessions channels
- IDuplexSessionRouter for duplex session channels
To add routing with a specific table, you'll first have to create the table. It is represented as FilterTable property in RoutingConfiguration class. Once you have created a configured RoutingConfiguration instance, then use RoutingBehavior object, which is of IServiceBehavior interface (a behavioral extension to ServiceDescription, see Day 5 for quick introduction to "service behaviors") and takes RoutingConfiguration as its constructor argument.
Once you have set routing configuration in above manner, then what to do next is to call AddServiceEndpoint() with (1) an interface type I listed above, (2) a binding for the router "(as a) service", and (3) an endpoint address for the router "(as a) service". (1) must be determined as to comply with the routed servers' requirements, and (2) and (3) represent the endpoint information for routers' client (and of course, a client must comply with (1) to properly communicate with the router).
Those four routing interfaces I listed above, all have Message as its one input argument (and output for IRequestReplyChannel). Since the contracts are very generic, a routing service can handle any communication between the client and the routed server (i.e. since they just take Message, it involves no typed serialization regardless of the contract of the routed service).
When a RoutingBehavior is called its ApplyDispatchBehavior() with a ServiceHostBase argument, it adds RoutingExtension to the service host. Then (1) it updates its service "instance context provider" (IInstanceContextProvider) that instantiates a RoutingService (which has no public constructor) and sets the routing configuration to it, and (2) creates a set of clients for the dispatched services internally.
There is another "endpoint behavior" SoapProcessingBehavior. It takes part in the router-to-service communication and adjusts messages (as I explained above e.g. updating message versions). You don't have to deal with it.
It is in very early stage and in fact I only tried request-reply style router.
Our Routing stack should work on .NET 3.5 too. Try "make" under mcs/class/System.ServiceModel.Routing - it will build mcs/class/lib/net20/System.ServiceModel.Routing.dll i.e. for 2.0 profile. There is nothing new I depended for its underlying layer.