static void

WCF Routing and discovery

Routing

MSDN scenarios
Routers have one or more client endpoints, and expose a service endpoint...

<system.serviceModel>
  <routing>
    <filters>
      <!-- filter logic -->
      <filter name="MatchAllFilter" filterType="MatchAll"/>
    </filters>
    <filterTables>
      <filterTable>
        <!--map filter to endpoint-->
        <add filterName="MatchAllFilter" endpointName="fwdEndpoint"/>
      </filterTable>
    </filterTables>
  </routing>

You can multicast (but not for request-reply as you'd get several replies!).

Each client endpoint can have a backupList (points to backupLists/backupList which is a list- it just works it's way down the list when it gets Timeouts or communication exception).

Code

You should host in IIS with configuration.

<%@ ServiceHost Language="C#"
Service="System.ServiceModel.Routing.RoutingService,
    System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35" %>

Here's a self-hosted version.

//create the service
var serviceHost = new ServiceHost(typeof(RoutingService));
 
//add the router endpoint
serviceHost.AddServiceEndpoint(
    //request-reply type
    typeof(IRequestReplyRouter),
    new WSHttpBinding(),
    "http://localhost/routingservice/router");
 
//add the client endpoint(s)- forwards the messages here
var client = new ServiceEndpoint(
    //use the router contract
    ContractDescription.GetContract(typeof(IRequestReplyRouter)),
    new WSHttpBinding(),
    new EndpointAddress("http://localhost/calculatorservice"));
 
//routing configuration
var rc = new RoutingConfiguration();
//a list of the clients
var endpointList = new List<ServiceEndpoint> { client };
//filter all messages to these clients
rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
//attach the behavior to the service host
serviceHost.Description.Behaviors.Add(new RoutingBehavior(rc));

Discovery

MSDN. Reference System.ServiceModel.Discovery.dll

Announce a service

By default, there are no announcements. Add an announcementEndpoint to the discovery behavior.

<behaviors>
  <serviceBehaviors>
    <behavior name="MyServiceBehavior">
      <serviceDiscovery>
        <announcementEndpoints>
          <endpoint name="udpEndpoint"
                    kind="udpAnnouncementEndpoint" />
        </announcementEndpoints>
      </serviceDiscovery>
    </behavior>
  </serviceBehaviors>

You can create an AnnouncementService, subscribe to its events (Online/OfflineAnnouncementReceived), and put it in a ServiceHost to selfhost with an UdpAnnouncementEndpoint.

Client discovery

The client sends a multicast Probe with Find with FindCriteria. You can set ContractTypeNames (each endpoint must match all these contracts). It returns zero or more records for services that support the criteria.

private EndpointAddress DiscoverServices()
{
    FindResponse findResponse;
    using (var discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint()))
    {
        findResponse = discoveryClient.Find(new FindCriteria(typeof (ICalculatorService)));
    }
    return !findResponse.Endpoints.Any() ? null :
        findResponse.Endpoints.First().Address;
}

A client can use DynamicEndpoint instead of a normal endpoint. Each time it is used, it discovers which endpoint it can use. Specify the contract description:

var contractDescription = ContractDescription.GetContract(typeof(ICalculator));