Aug 29, 2009

WS-Discovery 101: Basic Discovery

I could talk at you all day about why this is cool and why you need this, but how about a sample, shall we?  To start, we’ll convert an existing simple Client/Server application to use discovery to allow the client to find its service.

Service Modifications

These are the modifications that need to be done to the service to get it to respond to probe requests.  It is 100% configuration driven (nice!).

Add Discovery Service Behavior

In the demo service, we were already exposing metadata using a service behavior, so we can just add the behavior to the existing behavior configuration

<behavior name="MyServiceBehavior">
    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
    <serviceDiscovery />
</behavior>

So what we’ve done is instructed the service to publish endpoint information to clients that send a probe request, but we don’t get any use out of that until we tell the service what endpoints are important enough to tell anyone who asks about them.

Add Discovery Endpoint Behavior

The discovery endpoint behavior identifies those endpoints that need to be made available through WS-Discovery probe requests.

<system.serviceModel>
    <behaviors>
        <endpointBehaviors>
            <behavior name="PublishEndpoint">
                <endpointDiscovery />
            </behavior>
        </endpointBehaviors>

And here we are applying this behavior to the only endpoint we have:

<service behaviorConfiguration="MyServiceBehavior" name="BasicSample.Service.EchoService">
    <endpoint address="http://localhost:8080/EchoService/svc" 
              behaviorConfiguration="PublishEndpoint"
              binding="basicHttpBinding"
              name="httpEndpoint"
              contract="BasicSample.Service.IEchoService" />

Add UDP Endpoint for “Discoverers”

Without an endpoint to talk on, a service would never be free to handle incoming probe requests.  To do this, we simply add a UDP discovery endpoint longside the existing “httpEndpoint”.

<endpoint name="udpDisco" kind="udpDiscoveryEndpoint" />

That’s it!  When your service starts up, it’s ready to respond to WS-Discovery probe requests.

None of this is any good unless your client uses it.

Client Side Changes

Clients will send out a message to the network, looking for an appropriate service.  Unfortunately, this portion is not config-driven, however this process almost always will be slightly customized for the needs of the client, so it makes sense to do a bit of this discovery in code.

Remove the address and add a Dicovery Endpoint

First step is to prove to yourself that this works.  Delete the address!

When we are probing the network for a service, we need an endpoint capable of sending out these messages.

<client>
    <endpoint name="udpDisco" kind="udpDiscoveryEndpoint" />
    <!-- No address information! -->
    <endpoint binding="basicHttpBinding" contract="EchoProxy.IEchoService"
      name="BasicHttpBinding_IEchoService" />
</client>

Add Discovery Code

We need to add a reference in our client project to “System.ServiceModel.Discovery”.  This will give us access to a few classes we will need.

The only things left is to write the method that will search the network for the address of the service.  This will look something like this.

private static System.ServiceModel.EndpointAddress FindAddress()
{
    FindCriteria criteria = new FindCriteria(typeof(IEchoService));
    DiscoveryClient client = new DiscoveryClient();
    FindResponse response = client.Find(criteria);

    Console.WriteLine("Found {0} service(s).", response.Endpoints.Count);
    if (response.Endpoints.Count > 0)
    {
        return response.Endpoints[0].Address;
    }
    return null;
}

Notice here that we are searching the network for some pretty simple criteria (the service contract type) and that’s all.

Tying it all together

Now all we have to do is modify our typical client call to use the address that is returned from our FindAddress method.

private static void SendEcho(string textToEcho)
{
    EndpointAddress address = FindAddress();
    if (address != null)
    {
        using (EchoProxy.EchoServiceClient client = new EchoProxy.EchoServiceClient())
        {
            //use our newly found address
            client.Endpoint.Address = address;
            string result = client.Echo(textToEcho);
            Console.WriteLine(result);
        }
    }
}

That’s it!

Those of you following along at home will notice that this method takes some time to complete.  In the next post in the series, We’ll go over some ways you can optimize the time it takes for a probe to happen.

The code for this article is available here:

Aug 26, 2009

WS-Discovery 101: What is this thing?

This is a continuation of a series of posts on the new WS-Discovery features coming in WCF in NET 4.0. For the entire series, see here.

Windows Communication Foundation has had one of the most profound effects to the type of applications I see written since .NET 1.0 in my opinion. It made creating a Service Oriented Architecture that much more attainable.

If you look at any list of SOA Principles, there is (arguably) only one thing missing from Microsoft’s WCF strategy where it applies to SOA: Discoverability. This is what makes the addition of WS-Discovery so important to WCF. It paints a complete picture of a path to service orientation that was previously a lot of work to implement.

This is not to say that only those shooting for the lofty and often “enterprise” specific goal of SOA is the only reason to use WS-Discovery. You’d use WS-Discovery if you like any of these things:

  • Client finds endpoints that host a service without pre-configuration or a central store of endpoint information
  • Client finds all endpoints across a network that match certain criteria (contract, scope, etc).
  • Service is able to publish additional metadata about its endpoints to clients prior to use
  • Clients or a central service are notified when a service goes up or down

These are just a few of the features you get from WS-Discovery out of the box with very little configuration or coding.

Let’s talk about a few key words that will help when reading future articles.

Probing

Probing is the process of sending out a request to either an entire network subnet via a UDP multicast message (referred to as “Ad-Hoc discovery”) or to a central discovery proxy (proxies will be described at length in a later article).

Basically we are sending out a request saying “here’s what I’m looking for… is anyone out there that matches this criteria?”. Here’s a (hopefully) helpful diagram.

Any services that either don’t respond to discovery probes or aren’t a match for the criteria simply don’t respond to the probe request.

Announcement

Announcement is the process by which a service that has newly come up announces its availability to either a central discovery proxy or to all clients on the subnet. In this case, the client can take advantage of “push” notification messages from services coming online, rather than probing the network to find a matching service. Here’s another basic diagram.

Now we have a common language we can work with for the rest of the series.

Aug 25, 2009

WS-Discovery Presentation for DFWCSUG

I gave a presentation recently at Dallas / Ft. Worth Connected Systems User Group on the new WS-Discovery related features in .NET 4.0. I had a good time and I hope everyone learned something. I promised I would post my code and notes. Better late than never, so here is that post.

If you didn’t make it to the meeting, I’ll be posting a series of WS-Discovery posts that go over the various parts of the talk.

All demos are .NET 4.0 / Visual Studio 2010 solutions built for VS 2010 Beta 1, available here.

Slides

Demos

I had essentially two demos.

1. WS-Discovery basics. Converting an existing Client/Server application using WCF to use WS-Discovery to get address information and options for optimizing the performance. Includes discovery by probing and by announcement.

2. WS-Discovery Proxies. Creating an intermediary between clients and services that both caches discovery requests and routes discovery requests and announcements outside of the local subnet.

To keep tabs on my posts on these samples as they become available, see this web page: WS-Disco 101.

Next WS-Discovery Article: What is this thing?