Routing Messages in WCF 4.0
(May 2009 Issue)
October 30, 2009
In "What's New in WCF 4.0?" I provided an overview of the core new features forthcoming in WCF4.0 (to be released with Visual Studio 2010). As promised, I'll be exploringthese features in this column starting in this article with the RouterServiceintroduced in WCF 4.0. I should point out that I m basing this article on thePDC bits released in October 2009. These bits include a version of theRouterService called the ForwardingService reported to be renamed toRouterService before the release of .NET 4.0. For more information on WCF, see "Security Practices for WCF" and "Implementing SOA Patterns with WCF and .NET 4.0."
Why a RouterService?
Asoftware router does not replace the importance of appropriate software orhardware load balancers within your network infrastructure. It is, however,quite useful in situations where the use of a preexisting software or hardwareload balancer is not an option, or as a refinement beyond load balancing forapplication-specific distribution of messages. Thus, the following are possiblygood uses for a software router like the RouterService:
Load balancing with custom heuristics not provided by traditional software or hardware load balancers.
Introducing a security boundary to receive messages within the DMZ and forward safely to downstream services behind the DMZ.
Priority routing to application pools or servers according to message content.
Message redirection for service versioning according to message content.
Any number of other content-based routing scenarios.
Partitioning services so that messages targeting operations can be handled by different application pools or servers.
Implementinga custom router for any of these scenarios using WCF 3.x turns out to be a lotof work. The increased demand for custom routers thus led to WCF 4.0 includinga concrete implementation of a router that can handle messages over anyprotocol, with different messaging patterns (one-way, two-way, duplex), andwith a convenient filtering configuration.
RouterService Architecture
Froma high level, the purpose of the RouterService is to receive messages fromclients and forward those messages to the appropriate downstream services. Aparticular RouterService instance is associated with a set of filtering rules(a filter table and a set of filters) that are inspected prior to forwardingthe message. Filtering rules are at the heart of the RouterService because theydetermine the appropriate downstream service endpoint for each message.Downstream services may be hosted on the same machine as the router, ordistributed across several machines in a server farm. Figure 1 illustrates thisarchitecture.
Figure 1: High-level view of the RouterService architecture
Followthese steps to put the RouterService to use:
Choose a suitable hosting environment.
Expose one or more endpoints for clients.
Determine the appropriate binding configuration for each endpoint.
Configure the filter table and related filters to control routing.
I llwalk through these steps in the remainder of this article.
Hosting the RouterService
TheRouterService is a WCF service implementation and, thus, can be self-hosted orhosted in IIS like any other service. If the RouterService will be hosted in aclient application, you ll typically host the service in a Windows client(Windows Forms or WPF) and usually communicate over TCP or Named Pipes. If theRouterService will be hosted in a server deployment, your choice of IIS or aWindows Service will depend on the operating system. For Windows Server 2003machines you ll likely use IIS 6 for HTTP access and a Windows Service for TCP.For Windows Server 2008 machines you ll use IIS 7 and the Windows ProcessActivation Service (WAS) for all protocols. The point here is that you canchoose any hosting environment according to application requirements.
TheRouterService is located in the Microsoft.ProcessServer.Messaging assembly andis part of the Microsoft.ProcessServer.Messaging namespace (this may change).The code to self-host the service then requires a reference to that assemblyand the appropriate ServiceHost initialization code, as follows:
using (ServiceHost host = new ServiceHost(typeof(Microsoft.ProcessServer.Messaging.RouterService))){host.Open();Console.WriteLine("Press to terminate Router Host");Console.ReadLine();}You must provide a .svc endpoint for the RouterService type if you host the service with IIS:<%@ ServiceHost Service="Microsoft.ProcessServer.Messaging.RouterService" %>
Router Endpoints and Contracts
Regardlessof the host, you ll need to supply endpoints for the router in the servicemodel configuration section. The following code snippet illustrates a section that exposes an HTTP endpoint for the RouterService:
Thisendpoint is associated with the IRequestReplyDatagram service contractimplemented by the RouterService. Because the router must be able to processmessages with any SOAP action, this contract includes a single, catch-alloperation with an Action and ReplyAction set to * :
[ServiceContract(SessionMode = SessionMode.Allowed)]public interface IRequestReplyDatagram{[OperationContract(Action = "*", ReplyAction = "*")]Message ProcessMessage(Message message);}
TheRouterService also implements other contracts to support one-way and duplexcommunication, with similar settings to support any SOAP action. You may, forexample, expose a router endpoint that can handle duplex communication(callbacks) between clients and services. This endpoint would rely on theIDuplexSession contract:
TheIDuplexSession contract defines a callback contract named ISimplexSession.These contracts also support any SOAP action, in addition to requiring sessions(as shown in Figure 2).
[ServiceContract(SessionMode=SessionMode.Required,CallbackContract=typeof(ISimplexSession))]public interface IDuplexSession{[OperationContract(IsOneWay=true, Action="*")]void ProcessMessage(Message message);}[ServiceContract(SessionMode=SessionMode.Required)]public interface ISimplexSession{[OperationContract(IsOneWay=true, Action="*")]void ProcessMessage(Message message);}
Figure 2: The IDuplexSession contract defines a callback contract namedISimplexSession
Configuring Filters
Filterconfiguration is the heart of the RouterService. As clients send messages torouter endpoints, the RouterService evaluates filters to determine how toforward the message. This is done by associating a forwarding behavior with theservice type, as shown in Figure 3.
Figure 3: Filter configuration is the heart of the RouterService
Theforwarding behavior points to a filter table that lists relevant filters toevaluate as requests are processed by the RouterService. To optimize processingyou can restrict filtering to message headers rather than processing the entirebody of the message assuming the body of the message isn t required for filtering.
Thefilter table includes a list of filters to evaluate, indicating the prioritylevel of each filter and the client endpoint to use if the filter evaluates totrue. Filters are processed in order of priority; the first filter to match theincoming message is used to forward the message. The RouterService includes thenecessary code to construct a proxy based on the appropriate client endpoint.This filtering architecture is illustrated in Figure 4.
Figure 4: Filtering architecture
Figure5 shows a sample filter configuration. The priority 1 filter is examined beforethe priority 0 filter. The filter type for the priority 1 filter performs anXPath evaluation searching for a LicenseKey header. If the LicenseKey headermatches the value XXX , messages are forwarded to the priority host indicatedby the client endpoint configuration. If the LicenseKey header does not match,or a LicenseKey header is not present, the catch-all filter matches, andmessages are sent to the default host.
Figure 5: RouterService filtering configuration
Thereare several useful filter types from which to choose, including:
MatchAll: Useful as a priority 0 filter in the event other filters do not match.
XPath: Used to match header or body elements to a particular value.
Action: Used to route based on the SOAP action of a message.
And: Used to combine filters before a match can be satisfied.
Custom: Used to supply a custom filtering component where you have programmatic control of the filter result.
Binding Configuration
Therouter typically does not process protocol headers passed by the client, asthey are intended for the downstream service. As such, the router bindingshould purposely omit settings for security, reliable sessions, transactions,and other related protocols. The example I demonstrated earlier showed a routerendpoint using BasicHttpBinding which, by default, does not enable security onany other protocols. You can achieve a raw router binding for HTTP or TCP usinga CustomBinding configuration, as shown here:
Thismeans the router will forward messages without processing protocol headers; intheory, this means that clients can pass security headers without issue. Thecatch is that the router automatically adjusts the To header (a WS-Addressingheader), which causes problems because the modified To header will no longer besigned something the service will expect if security is enabled. For HTTPrequests, you can disable the modification of the To header by setting manualaddressing to true, as shown here:
Note: Manual addressing is not supported over TCP for two-way messaging. I discussed issues like this in the following MSDN articles related to building a custom WCF 3.x router:
Conclusion
Thenew RouterService to be released with WCF 4.0 removes the pain of building acustom router for the majority of pass-through router scenarios where messagesare to be forwarded without processing based on application heuristics. In thisarticle I explained the fundamentals of this new RouterService based on the PDCbits. The code samples accompanying this article illustrate many differentfiltering scenarios, and will be updated as new releases are available.
Download the samples for this article at www.dasblonde.net/downloads/asppromay09.zip.
Read more about:
MicrosoftAbout the Author
You May Also Like