Creating a WCF 4.0 Routing Service

By | August 18, 2011

One of the new WCF 4.0 features is routing. Routing can be used for multiple purposes:

– Service versioning
– “Extended” load balacing
– Content-based routing scenario
– Service partitioning
– Protocol bridging
– etc.

In this example, I have two person services. One in London and one in Paris. The client knows only the WCF router.
The router filters the client request and calls the appropriate person service.
London uses http and Paris uses net.tcp binding. The clients and the router are communicating via http.
WCF router

The contract for the both person services contains one method:

 
[ServiceContract]
public interface IPersonService
{
    [OperationContract]
    Person GetPerson(PersonFilter filter);
}

Implementations (London/Paris):


// London service
public class PersonService : IPersonService
{
    public Person GetPerson(PersonFilter filter)
    {
        if (filter.Location.ToLower() == "london")
            return new Person() {  Firstname = "John", Lastname = "Owen" };
        return null;
    }
}

// Paris service
public class PersonService : IPersonService
{
    public Person GetPerson(PersonFilter filter)
    {
        if (filter.Location.ToLower() == "paris")
            return new Person() { Firstname = "André", Lastname = "Moutiers" };
        return null;
    }
}

The London service uses basicHttpBinding. Here is the configuration.


  
    
      
        
        
          
            
          
        
      
    
  

And the Paris service uses netTcpBinding:



  
    
      
        
        
          
            
          
        
      
    
  

The services are running in console applications. (self-hosted)

// London
class Program
{
    static void Main(string[] args)
    {
        var host = new ServiceHost(typeof(PersonService.PersonService));
        host.Open();
        Console.WriteLine("London PersonService running.");
        Console.ReadLine();
        host.Close();
    }
}

// And paris
class Program
{
    static void Main(string[] args)
    {
        var host = new ServiceHost(typeof(PersonService.PersonService));
        host.Open();
        Console.WriteLine("Paris PersonService running.");
        Console.ReadLine();
        host.Close();
    }
}

The WCF router must know the location of these services. And by filtering the client request, the router has to
decide which service has to be called. The most things are done in the config file. Read the XML comments.


  
    
      
      
        
          
          
          
        
      
    
    
      
      
        
        
        
      
      
        
        
          
          
        
      
    
    
      
      
        
        
          
            
          
        
      
    
    
    
      
      
    
  

WCF router hosting. The “RoutingService” class is a .NET 4.0 class.

class Program
{
    static void Main(string[] args)
    {
        var host = new ServiceHost(typeof(RoutingService));
        host.Open();
        Console.WriteLine("Routing running.");
        Console.ReadLine();
        host.Close();
    }
}

We have now three services:

Name Function Address
WCF router Routing http://localhost:9000/PersonServiceRouter
London service Data service http://localhost:8000/Personservice
Paris service Data service net.tcp://localhost:8500/Personservice

The client has just to know the WCF router.
This code here, calls the service method “GetPerson” with a filter.
The Property “PersonFilter.Location” is important for the WCF router. The configurated filter (see WCF router config)
checks the value of the “Location” and calls the appropriate service (London or Paris).

class Program
{
    static void Main(string[] args)
    {
        // create proxy object
        var binding = new BasicHttpBinding();
        var endpoint = new EndpointAddress("http://localhost:9000/PersonServiceRouter");
        var proxy = ChannelFactory.CreateChannel(binding, endpoint);
         
        // Call WCF router with param "london". -> London PersonService is called.
        CallService(proxy, "london");
        // Call WCF router with param "paris". -> Paris PersonService is called.
        CallService(proxy, "paris");

        Console.ReadLine();
    }

    static void CallService(IPersonService proxy, string location)
    {
        Console.WriteLine("-------------------------");
        Console.WriteLine("Service URL: http://localhost:9000/PersonServiceRouter");
        Console.WriteLine("Filter: " + location);

        // Set the person filter
        var filter = new PersonFilter() { Location = location };
        var person = proxy.GetPerson(filter);

        Console.WriteLine("Firstname: {0}, Lastname: {1}", person.Firstname, person.Lastname);
        Console.WriteLine("-------------------------");
        Console.WriteLine(string.Empty);
    }
}

This is it.
WCF router example

And here is a printscreen of my VS.NET solution:
WCF router solution

EDIT: Here you can download the solution: WcfRouting

  • varun

    Nice explanation. Please provide me source code
    for the above

  • admin

    Hi Varun
    I uploaded the solution.

  • varun

    Hi,
    Thanks
    Code is fully compiled but i am getting error at run-time.
    There was no endpoint listening at http://localhost:9000/PersonServiceRouter that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.

    how i will set end point for all the services

  • admin

    Hi. You have to start the London-, Person- and RouterService and then you can start the client exe.

  • varun

    How i will set base path for London .In your case it is
    http://localhost:8000/Personservice
    What will be in my case?

  • admin

    It’s the same url for you too. You have to start all three services. The router doesn’t start the london/paris services.
    Nevertheless, the service address is defined in the app.config file of london/person service. If you change the port, you have to reconfigure the routing config (app.config)

  • varun

    I am using the same solution as provided by you
    why i am getting errors and how i will start all the three services

  • admin

    There are two solution:
    1) Build the solution. Go to the bin folder and start the exe files of all services.
    2) Set for example the london service as “startup project” and press ctrl+f5. Then set paris service as “startup project” and press ctrl+f5 and the same for the routing service. Then set startup project to the client project and press f5.

  • varun

    I am getting error in London and Router but paris is running properly. Cany u check again this solution plz

  • admin

    I checked it before I uploaded the solution. Maybe the ports are already occupied?
    You have to start first the person (paris/london) services and then the router.

  • varun

    I started firstly for paris ok but when i started for Router, again i got error, Do u have video for this

  • admin

    did you started london to?????

    Router only works when both person services are up. What error do you get when starting the london service??

  • varun

    I am getting access denied error, if you want i will send u
    screenshot

  • admin

    Did you run the services as administrator?

    Yes. Send me a screenshot.
    I think it could be something like this: http://stackoverflow.com/questions/885744/wcf-servicehost-access-rights

    Try to change the binding of the london service to net.tcp (like paris). You have to change the binding in the router and london config files.

  • varun

    Thanks in other computer its working fine but in my
    computer due to some access rights

    I need your favour. can you provide me one example
    of the same using database.

    I followed one example source code is different and reading code is different
    http://www.dotnetcurry.com/ShowArticle.aspx?ID=385
    I didn’t get the output
    I want the same example explaned by you with the source code

    Please provide me source code with database

  • admin

    There is no big difference. The database connection has nothing to do with wcf routing…
    In my example, the both services london/paris would connect to a specific DB and return person data.

  • varun

    Please create one scenario in your case that will be connected to database and return person data.

    how london and paris will be connected to database and return data.

    please create one case

  • admin

    I’m sorry. This has really nothing to do with WCF routing. You just have to create an easy db connection (SqlConnection, Entity Framework etc.)
    Ask google and you will find enough examples for this.

  • Very good explanation.

  • Naveed Anwar

    Very good example. Thanks

  • gaurav

    Very good example ……….Thanks I got error(There was no endpoint listening at http://localhost:9000/PersonServiceRouter ) while i was run vs in simple mode… and i was change my vs mode in administrative mode . i did not get error..

  • DaMi

    Yes. It’s a self-hosted service. In that case you need more rights.

  • assada

    DSFSD

  • Kundan Saw

    Ultimate explanation. really very helpful. thanks

  • DaveDave

    Wow this is a great explanation and exactly what I needed. Just one question, how can i get the WSDL url or file from this example? Im tryng to call the services from a java client.. Cheers!

  • dmicic

    Hi David. I’ve never done this with WCF routing. But this example here should help: http://stackoverflow.com/questions/17476156/wcf-how-to-combine-several-services-into-single-wsdl/19890944#19890944