A Simple Discovery Scenario


Last entry we talked about the benefits of WCF-Discovery, this time we’ll delve into a hello world example. You have a WCF Calculator Service and a client that needs to locate it. In order to find the service the client sends out a query. This query can be sent to a Proxy server (more about this later) or it can be multicast out over UDP. The WCF-Discovery solution provides an easy way for clients to do this. All you have to do is point your client to use a DynamicEndpoint such as this:

DynamicEndpoint dynamicEndpoint = new DynamicEndpoint(
    ContractDescription.GetContract(typeof(ICalculatorService)),
    new NetTcpBinding());
CalculatorServiceClient client = new CalculatorServiceClient(dynamicEndpoint);

That’s all there is to it. Under the covers, we create a client (known as DiscoveryClient) that looks for services based on the default settings. The client created by the DynamicEndpoint will look for a service, matching the service type, over a udp multicast endpoint. The contract, binding and address for this endpoint are set to the values specified by the protocol; pre-defined endpoints such as these are referred to as StandardEndpoints.

Packets multicast over UDP have the limitation that only listeners in the same subnet will receive them, unless your routers are specifically configured to forward the packets. If the service is on the same subnet and is discoverable over the UdpDiscoveryEndpoint then it will respond back to the client with its metadata if it matches the client’s query. All of this requires two lines of change in your configuration from the service end. Here are the modifications needed to your App.config:

<services>
  <service behaviorConfiguration="CalculatorBehavior" name="Microsoft.Samples.Discovery.CalculatorService">
    <!--Add Discovery Endpoint-->
    <endpoint name="udpDiscoveryEpt" kind="udpDiscoveryEndpoint" />
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="CalculatorBehavior">
      <!--Add Discovery behavior-->
      <serviceDiscovery /> 
    </behavior>
  </serviceBehaviors>
</behaviors>

That’s how simple it is, you add a behavior to your service, and then you add a service endpoint that designates where discovery service will look for WS-Discovery messages. This is just as easy to do programmatically also… more about that later though. With the serviceDiscovery behavior added, the service responds back to the client's query and provides it the metadata so that the client can connect to the service.

You can check out the working code in the .NET Beta1 discovery sample here: http://msdn.microsoft.com/en-us/library/dd483369(VS.100).aspx. On the client side, this sample uses the DiscoveryClient directly. A client implementation that uses DynamicEndpoint can be found here: http://msdn.microsoft.com/en-us/library/dd807387(VS.100).aspx


Comments (2)
  1. jabrouni1 says:

    Thats exciting!!But it opens a lot of questions. The importance of ws-discovery is not documented anywhere. The only selling point seems to be that the client can adapt to service endpoint changes.And the ability for the client to know when the service comes up or goes down. A little explanation on the  possible scenarios could go a long way in people adapting to this at a very early stage. Also what if i have a service with discovery enabled and hosted over a internet?Will that be discoverable?As most of the discussions seem to emphasize the LAN limitation. These questions are being posed possibly because i am not well informed about WS-Discovery on WCF. But that again leads to lack of proper information. Thanks for your time

  2. Alexander says:

    Hi there!

    I have to admit there is one thing I don`t like.

    All the examples (msdn.microsoft.com/…/dd456785.aspx  or  msdn.microsoft.com/…/ee354381.aspx or this one here) expect me to have already used svcutil.exe to create the proxy class. So I have to know the ABC, before I can start searching?

    the "sexy" use case imho would be: I get a contract -a shared assembly- and want to use it by dynamically building my proxy with sth like  

    ChannelFactory<IService> factory = new ChannelFactory<IServiceChannel>(BINDING?!?, discoveredAddress);

    IServiceChannel client = factory.CreateChannel();

    But the EndpointDiscoveryMetadata don`t support me with the binding. But that -although it seems like the ws-discovery specification indeed doesn`t contain the need to supply a client with the binding information- would have been a nice thing to have. Do i really have to use the found address to search for an mex-endpoint for getting the binding dynamically?

    The discovery implementation would be so nice if one could get the binding easily ;(

    Best regards!

    Alexander

Comments are closed.

Skip to main content