Click here to Skip to main content
Click here to Skip to main content

Getting Started with WCF 4.0 Routing Service

By , 17 Jul 2012
 

Introduction 

Routing is the process of picking and directs messages to the proper endpoints through transitional. That is, the purpose of the Routing Service is to receive messages from clients and frontward those messages to the suitable downstream services. Downstream services may be hosted on the same machine or distributed across several machines in a server farm. Routing provides the facility of isolating these services directly accessible from the client application through router. Client application have knowledge of only one service which further routes request from the client to the specific service.

WCF 4.0 introduces a new service called Routing Service that acts as a message router which has a built-in way for routing WCF service calls. This Routing Service is available under the new assembly System.ServiceModel.Routing.  If you want to know more about this please have a look on this link [^]  


In the above figure,the Client application have knowledge of WCF Routing Service which further routes request to the specific services WCF Service1 or WCF Service2 or WCF Service3.

WCF Routing Service

WCF supplies a class for routing called RoutingService which is located underneath the namespace System.ServiceModel.Routing. These services can be hosted in any service host available EXE’s, Windows Services or IIS. When you configure routing service you need to configure routing service endpoint (Address, Binding, Contract) like every other service. Unlike other service contracts, the Routing Service can be configured with any of the contracts listed below. Based on these contracts the WCF communication channels are established.

ISimplexDatagramRouter: Defines the interface required for processing messages from simplex datagram.

ISimplexSessionRouter: Defines the interface required to process messages from simplex session channels.

IRequestReplyRouter: Defines the interface required to process messages from request-reply channels.

IDuplexSessionRouter: Defines the interface required to process messages from duplex session channels. 

You can get the details of these integrated contracts through this link [^

Service Configuration  

<services>
      <!-- Routing service with endpoint definition -->
      <service name="System.ServiceModel.Routing.RoutingService"
               behaviorConfiguration="routingBehv">
        <endpoint
          address="/hello"
          binding="wsHttpBinding"
          contract="System.ServiceModel.Routing.IRequestReplyRouter"
          name="HelloService"/>
        <endpoint
         address="/oneway"
         binding="basicHttpBinding"
         contract="System.ServiceModel.Routing.ISimplexDatagramRouter"
         name="OneWayService"/>
        <endpoint
         address="net.tcp://localhost:8733/HelloServiceRouter/duplex"
         binding="netTcpBinding"
         contract="System.ServiceModel.Routing.IDuplexSessionRouter"
         name="DuplexService"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:9000/HelloServiceRouter"/>
          </baseAddresses>
        </host>
      </service>
    </services>    

In this configuration section, we see that the service name is System.ServiceModel.Routing.RoutingService and I have specified different endpoint with different contracts provided by the RoutingService. At this point, the services can listen the incoming request and also need to know what they should do once they have received the request. To do that, we need to enable routine service and configure it accordingly.

Routing Configuration 

 <routing>    
      <filters>
        <filter name="HelloServiceFilter" filterType="EndpointName" filterData="HelloService"/>
        <filter name="OneWayServiceFilter" filterType="EndpointName" filterData="OneWayService"/>
        <filter name="DuplexServiceFilter" filterType="EndpointName" filterData="DuplexService"/>
      </filters>
      <filterTables>
       <filterTable name="filters">
          <add filterName="HelloServiceFilter" endpointName="HelloService" />
          <add filterName="OneWayServiceFilter" endpointName="OneWayService"/>
          <add filterName="DuplexServiceFilter" endpointName="DuplexService"/>
        </filterTable>
      </filterTables>
    </routing> 

The  routing section consists of two sections filters and filterTables. All the filters that are created for the routing are located in the filters section. For each filter we have to specify the name and the type. Here, the filterData is EndpointName. There are some different kind of filter types are available, 

EndpointName : A custom message filter for use solely in the Routing Service, which filters messages based on the name of the service endpoint.

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.

Here you will get the details explanation about the filter Types. 

 In above configuration section specially in filterTable section  we also observe that filterName=”HelloServiceFilter” that will match with the name in filter section.The endpointName points to clients configuration. That is, if the endpointName is “HelloService” It means that there is a client configuration section that map with this name. As example ,

  <endpoint address="http://localhost:8732/HelloWorldService/HelloService/"
                binding="wsHttpBinding"
                contract="*"
                name="HelloService"/> 

Client Configuration 

Finally, we need to specify the endpoint to call when a message passes the filter.

 <client>
      <endpoint address="http://localhost:8732/HelloWorldService/HelloService/"
                binding="wsHttpBinding"
                contract="*"
                name="HelloService"/>
      <endpoint address="http://localhost:8732/OneWayService/"
                binding="basicHttpBinding"
                contract="*"
                name="OneWayService"/>
      <endpoint address="net.tcp://localhost:8734/DuplexService/"
                binding="netTcpBinding"
                contract="*"
                name="DuplexService"/>
    </client>

Here “*” refers the all Matches contract. That's it. Now lets move into the code portion. 

 

Using the code 

The Solution contains three projects for the services namely HelloWorldService, OneWayService and DuplexService , One is for Client and Two for Server(one is for Self Hosting and other is for IIS Hosting). So the Solution Structure is like that, 

The service contract for HelloWorld Service,

    [ServiceContract]
    public interface IHelloService
    {
        [OperationContract]
        string SayHi(string msg);
    } 

For OneWayService,  

 [ServiceContract]
    public interface IHelloService
    { 
        [OperationContract(IsOneWay = true)]
        void SayHi(string msg);
    } 

For DuplexService,

    [ServiceContract(CallbackContract = typeof(ICallbackDuplexService), SessionMode = SessionMode.Required)]   
    public interface IHelloService
    {
        [OperationContract]
        string SayHi(string msg);
    } 

Callback Contract,

 public interface ICallbackDuplexService
    {
        [OperationContract]
        string Reply(string msg);
    } 

 If you want to know how WCF Callback works please have a look on this link [^

Client Code, 

 If you want to use self hosting then please use this code portion,  

Console.WriteLine("************ Self Hosting**************");

            Console.WriteLine("\n\n------------------------------------------------------");
            Console.WriteLine("\n\n Binding = WSHttpBinding");
            Console.WriteLine("\n\n endpoint = http://localhost:9000/HelloServiceRouter/hello");

            var binding = new WSHttpBinding();
            var endpoint = new EndpointAddress("http://localhost:9000/HelloServiceRouter/hello");
            var proxy = ChannelFactory<IHelloService>.CreateChannel(binding, endpoint);
        
            Console.WriteLine("\n\n Reply from Server :" + proxy.SayHi("Hi"));
            Console.WriteLine("\n\n------------------------------------------------------");

            Console.WriteLine("\n\n------------------------------------------------------");
            Console.WriteLine("\n\n Binding = NetTcpBinding");
            Console.WriteLine("\n\n endpoint = net.tcp://localhost:8733/HelloServiceRouter/duplex");
            var callback = new MyClientCallback();
            InstanceContext ctx = new InstanceContext(callback);

            var netbinding = new NetTcpBinding();
            var netendpoint = new EndpointAddress("net.tcp://localhost:8733/HelloServiceRouter/duplex");
            var netproxy = DuplexChannelFactory<Rashim.RND.WCFRouting.DuplexService.IHelloService>.CreateChannel(ctx, netbinding, netendpoint);
            
            Console.WriteLine("\n\n Reply from the Server:" + netproxy.SayHi("Hi"));
            Console.WriteLine("\n\n------------------------------------------------------");

            Console.WriteLine("\n\n------------------------------------------------------");
            Console.WriteLine("\n\n Binding = BasicHttpBinding");
            Console.WriteLine("\n\n endpoint = http://localhost:9000/HelloServiceRouter/oneway");
            var onewaybinding = new BasicHttpBinding();
            var onewaynetendpoint = new EndpointAddress("http://localhost:9000/HelloServiceRouter/oneway");
            var onewaynetproxy = ChannelFactory<Rashim.RND.WCFRouting.OneWayService.IHelloService>.CreateChannel(onewaybinding, onewaynetendpoint);
            onewaynetproxy.SayHi("Hi");
           
            Console.WriteLine("\n\n oneway binding is working");
            Console.WriteLine("\n\n------------------------------------------------------");
            Console.WriteLine("************ ++++++++++++++++**************"); 

If you want to use IIS hosting then you might use this code portion. In my case i have used the local webserver, 

   Console.WriteLine("************ IIS Hosting**************");
            
            Console.WriteLine("\n\n------------------------------------------------------");
            Console.WriteLine("\n\n Binding = WSHttpBinding");
            Console.WriteLine("\n\n endpoint = http://localhost:5725/RouterService.svc/hello");

            var binding = new WSHttpBinding();
            var endpoint = new EndpointAddress("http://localhost:5725/RouterService.svc/hello");
            var proxy = ChannelFactory<IHelloService>.CreateChannel(binding, endpoint);
            Console.WriteLine("\n\n Reply from Server :" + proxy.SayHi("Hi"));
            Console.WriteLine("\n\n------------------------------------------------------");



            Console.WriteLine("\n\n------------------------------------------------------");
            Console.WriteLine("\n\n Binding = WSDualHttpBinding");
            Console.WriteLine("\n\n endpoint = http://localhost:5725/RouterService.svc/duplex");          

            var callback = new MyClientCallback();
            InstanceContext ctx = new InstanceContext(callback);

            var netbinding = new WSDualHttpBinding();
            var netendpoint = new EndpointAddress("http://localhost:5725/RouterService.svc/duplex");
            var netproxy = DuplexChannelFactory<Rashim.RND.WCFRouting.DuplexService.IHelloService>.CreateChannel(ctx, netbinding, netendpoint);

            Console.WriteLine("\n\n Reply from the Server:" + netproxy.SayHi("Hi"));
            Console.WriteLine("\n\n------------------------------------------------------");

            Console.WriteLine("\n\n------------------------------------------------------");
            Console.WriteLine("\n\n Binding = BasicHttpBinding");
            Console.WriteLine("\n\n endpoint = http://localhost:9000/HelloServiceRouter/oneway");

            var onewaybinding = new BasicHttpBinding();
            var onewaynetendpoint = new EndpointAddress("http://localhost:5725/RouterService.svc/oneway");
            var onewaynetproxy = ChannelFactory<Rashim.RND.WCFRouting.OneWayService.IHelloService>.CreateChannel(onewaybinding, onewaynetendpoint);
            Console.WriteLine("\n\n oneway binding is working");
            Console.WriteLine("\n\n------------------------------------------------------");
            Console.WriteLine("************ ++++++++++++++++**************");    

 NOTE: In Rashim.RND.WCFRouting.DuplexService  there are two configuration sections for netTcpBinding and wsDualHttpBinding . If you want to use Rashim.RND.WCFRouting.Router please comment out the netTcpBinding configuration sections otherwise comment out the wsDualHttpBinding configuration section.  

Okay now everything is ready right!!

What else   

Run the project Rashim.RND.WCFRouting.Router. You might need to run it as admin mode(Better if you run the exe as a Admin). And then run the project Rashim.RND.WCFRouting.Client by commenting out the Self hosting portion in Program.cs. You can also use  RouterHostingInIIS . If you want to use RouterHostingInIIS , you need to run the RouterHostingInIIS project and then run the Rashim.RND.WCFRouting.Client by commenting out the specific IIS hosting  code portion  in Program.cs.Or you might set up the RouterService.svc in IIS and then change the configuration file accordingly. 

 

That's it

That's it for now, I hope this article and the result help you to start working with WCF 4.0 Routine Service.  

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Md. Rashim uddin
Software Developer (Senior) KAZ Software Limited.
Bangladesh Bangladesh
I am nothing more than a simple man with the high vision of evolving multifaceted software systems by using my technical and interpersonal skills which will complement my professional growth. I feel enjoyment to take challenges to resolve those technical problems which are yet to be solved.
 
My Blog: http://rashimuddin.wordpress.com/
 
My Email: rashimiiuc at yahoo dot com
Follow on   Twitter

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionExcellentmemberMusthafa (Member 379898)7-Nov-12 21:49 
QuestionadmirablememberAlireza_136220-Jul-12 23:19 
GeneralMy vote of 4memberSaiyed Alam18-Jul-12 10:03 
GeneralMy vote of 5memberdexterama18-Jul-12 3:32 
GeneralRe: My vote of 5memberMd. Rashim uddin18-Jul-12 3:42 
GeneralMy vote of 5memberMahmud Hasan17-Jul-12 23:55 
GeneralRe: My vote of 5memberMd. Rashim uddin18-Jul-12 0:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130617.1 | Last Updated 18 Jul 2012
Article Copyright 2012 by Md. Rashim uddin
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid