Welcome to MSDN Blogs Sign in | Join | Help

WS-Discovery is now an OASIS approved standard

As of today (July 1st 2009) Web Services Dynamic Discovery (WS-Discovery) Version 1.1  is officially an OASIS standard (http://lists.oasis-open.org/archives/tc-announce/200906/msg00002.html). Discovery bits included in the .NET 4.0 Beta1 package implement this specification.

 

Posted by vipulm | 0 Comments

Discovery Find and FindCriteria

A Discovery Find is initiated by a client in order to discover one or more services, and is one of the main actions in Discovery. Performing a Find sends a WS-Discovery Probe message over the network. Matching services reply with WS-Discovery ProbeMatch messages (Read more about WS-Discovery messages in the specification). Let's look at a few of the classes in .Net Framework 4 which you can use when doing a Discovery Find operation.

 

 

The DiscoveryClient class makes performing discovery client operations easy. It contains a Find() method, which performs a (blocking) synchronous find, and a FindAsync() method, which initiates a non-blocking asynchronous find. Both methods take a FindCriteria parameter, and provide results to the user through a FindResponse object.

 

 

FindCriteria has several properties, which can be grouped into search criteria (specifying what services you’re looking for) and find termination criteria (how long the search should last).

 

Search Criteria:

·         ContractTypeNames – Optional. The contract name of the service being searched for, and the criteria typically used when searching for a service.

If more than one contract name is specified, only service endpoints matching ALL contracts will reply. Note that in WCF, an endpoint can only support one contract.

 

·         Scopes – Optional. Scopes are absolute URIs which are used to categorize individual service endpoints.     

 

      Let's take an example to understand Scopes better. Suppose there are multiple printers in different levels of a building. A user in the first level who wants to search for a printer would prefer to find a one which is present in the same level. If he searches using only the contract then all the printers will respond back. To futher fine tune the responses, the user can decorate the endpoints of the Printers using scopes. The user can then specify the scopes as part of the FindCriteria and only services that have endpoints which match the scopes will respond. Another example could be where there is one single service with two (or multiple) endpoints. One endpoint could be an external facing BasicHttpBinding endpoint and the other could be an internal facing NetTcpBinding endpoint. The user can decorate these endpoints with appropriate scopes to categorize them.

 

If more than one scope is specified, only service endpoints matching ALL scopes will reply.

 

·         ScopeMatchBy – ScopeMatchBy specify the matching algorithm to use while matching the scopes in the Probe message with that of the endpoint

.

There are five supported scope-matching rules, as described in the MSDN documentation. If you do not specify a scope-matching rule, FindCriteria.ScopeMatchByPrefix is used.

FindCriteria.ScopeMatchByExact does a basic case-sensitive string comparison.

FindCriteria.ScopeMatchByPrefix does matching by segments separated by "/". So a search for http://microsoft/building1 will match a service with scope http://microsoft/building1/floor1. Note that it won't match http://microsoft/building100, because the last two segments don't match.

FindCriteria.ScopeMatchByLdap does segment matching using an LDAP URL.

FindCriteria.ScopeMatchByUuid does exact matching for a UUID string.

FindCriteria.ScopeMatchByNone will only match services which don't have any scope specified.

 

It is also possible to specify custom ScopeMatchBy rule, but only custom services which support the type will respond. More on how to implement custom scope-matching in a future post.

 

Note: A Find using an empty FindCriteria (with no search criteria specified) will match all services listening on the network.

 

Termination Criteria:

·         Duration – The maximum time to wait for replies from services on the network. The default duration is 20 seconds.

·         MaxResults – The maximum number of replies to wait for. If MaxResults replies are received before Duration has elapsed, the Find will end. The default MaxResults is int.MaxValue.

 

 

FindResponse has an Endpoints collection property which contains any replies sent by matching services on the network. If no services replied, the collection will be empty. If one or more services replied, each reply will be stored in an EndpointDiscoveryMetadata object, which contains the address, contract, and some additional information about the service.

 

 

Here's how it all looks in a snippet of code:

// Create DiscoveryClient

DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());

 

// Create FindCriteria

FindCriteria findCriteria = new FindCriteria(typeof(IPrinterService));

findCriteria.Scopes.Add(new Uri("http://www.microsoft.com/building1/floor1"));

findCriteria.Duration = TimeSpan.FromSeconds(10);

 

// Find ICalculatorService endpoints           

FindResponse findResponse = discoveryClient.Find(findCriteria);

 

Console.WriteLine("Found {0} ICalculatorService endpoint(s).", findResponse.Endpoints.Count)

Discovery Announcements

Now that you are familiar with some Discovery Concepts, let’s find out more about Announcements. I will use the terms:

-          Target Service: an endpoint that makes itself available for discovery,

-          Client: an endpoint that searches for Target Services,

-          Discovery Proxy: an endpoint that facilitates discovery of Target Services by Clients.

When a client needs to find a service, one way to search for it is to poll for available services. Another way is to listen for the Hello and Bye announcements. With this approach, the network traffic is reduced and the Client can learn about the presence/departure of the service as soon as announcements are received.

When a service joins a network and becomes discoverable, it sends a multicast Hello message that contains key information about the target service, announcing its availability to listening clients. Similarly, when a Target Service leaves a network, it sends a Bye message announcing its departure. This defines the ad-hoc mode of operation.

To scale to a large number of endpoints, the Discovery protocol defines a managed mode of operation, when a Discovery Proxy is used to find Target Services. In this case, the target service sends unicast announcement messages to a Discovery Proxy. When a Discovery Proxy detects a probe or resolution request sent multicast on an ad hoc network, it sends an announcement for itself, letting the Clients know of its existence.

WCF Discovery offers the AnnouncementEndpoint and UdpAnnouncementEndpoint standard endpoints to allow services and clients to easily send Hello and Bye announcements. Here are the simple steps to configure them to use announcements:

On the service side:

To configure the service to send announcements, we need to add a ServiceDiscoveryBehavior with an announcement endpoint. Considering the CalculatorService we talked about in previous samples and a ServiceHost called serviceHost that hosts it, we can programmatically add the behavior like this:

ServiceDiscoveryBehavior serviceDiscoveryBehavior = new ServiceDiscoveryBehavior();

// Announce the availability of the service over UDP multicast

serviceDiscoveryBehavior.AnnouncementEndpoints.Add(new UdpAnnouncementEndpoint());

// Make the service discoverable over UDP multicast

serviceHost.Description.Behaviors.Add(serviceDiscoveryBehavior);                

The behavior can also be configured through the configuration file:

<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>

        <announcementEndpoints>

          <endpoint kind="udpAnnouncementEndpoint" />

        </announcementEndpoints>

      </serviceDiscovery>

    </behavior>

  </serviceBehaviors>

</behaviors>

With this simple change, services will send announcements when starting and closing. If the services are aborted, the messages are not sent.

On the client side:

We need to host an AnnouncementService and subscribe to the OnlineAnnouncementReceived and OfflineAnnouncementReceived events.

// Create an AnnouncementService instance

AnnouncementService announcementService = new AnnouncementService();

 

// Subscribe the announcement events

announcementService.OnlineAnnouncementReceived += OnOnlineEvent;

announcementService.OfflineAnnouncementReceived += OnOfflineEvent;

 

// Create ServiceHost for the AnnouncementService

using (ServiceHost announcementServiceHost = new ServiceHost(announcementService))

{

    // Listen for the announcements sent over UDP multicast

    announcementServiceHost.AddServiceEndpoint(new UdpAnnouncementEndpoint());

    announcementServiceHost.Open();

 

    Console.WriteLine("Press <ENTER> to terminate.");

    Console.ReadLine();

}

When an offline/online announcement is received, we have access to the endpoint discovery metadata through the AnnouncementEventArgs:

static void OnOnlineEvent(object sender, AnnouncementEventArgs e)

{

    Console.WriteLine("Received an online announcement from {0}", e.EndpointDiscoveryMetadata.Address);

}

 

static void OnOfflineEvent(object sender, AnnouncementEventArgs e)

{

    Console.WriteLine("Received an offline announcement from {0}", e.EndpointDiscoveryMetadata.Address);

}

You can check out the working code in the Announcements .NET Beta1 discovery sample. Beyond this simple usage, the user can extend the announcement model (eg. custom announcements). WCF Discovery also offers the possibility to send announcements explicitly, using AnnouncementClient. Stay tuned for more about this in a future post.

Posted by OanaPlaton | 0 Comments
Filed under: , ,

Discovery Concepts

                The last entry covered a simple discovery example. Before we get into more complex scenarios, let’s cover some of the core concepts behind WCF-Discovery. The entry below covers the main components, exposed functionality as well as the modes of operation of WCF-Discovery.

Discovery Components

components 
In any application architecture, there can be three types of components utilizing discovery. As the picture above shows, Discovery involves a client, a service, and/or a Discovery Proxy. Without resorting to strict definitions, here is how you can think of them and their capabilities:

  • A Client is an entity that is looking for services and utilizes the “DiscoveryClient” to search for them. A client may also host an “Announcement Service” if it wants to listen for announcements from services.
  • A Service is a WCF service that has endpoints which can be discovered. A Service adds a ServiceDiscoveryBehavior in the service host description, which enables it to respond to find requests from clients. A service may also host an announcement client if it wants to announce itself. 
  • A Discovery Proxy – This is a centralized repository that knows about services. This is a not a required component and its necessity is completely dependent on your use case. The framework does not include an implementation of a proxy; though it does provide the building blocks for you to easily create one. There are several uses for a Proxy and we’ll cover this component in detail in subsequent posts.

Discovery Functionality
The real key is, how can a Client become aware of a Service? As hinted at above, discovery functionality can be broken down into two areas: find/ resolve operations and announcements.

The find/resolve functionality is characterized by a client looking for a service. This can be broken down further into: Find and Resolves

  • Find: If a client is looking for a service based on criteria such as the service type, or some scopes, it sends out a Probe message. The recipient of the probe, either a service or a proxy responds back to the client with the appropriate service metadata.
  • Resolve: A resolve is used by client to locate a service based on its endpoint address. This is useful when the endpoint address is not network addressable.

Another functionality open to users is Announcements. In this case Services can announce themselves to the network and clients can be configured to listen for such announcements. In the default case a service sends out a hello message when it comes online and a bye message when going offline. This pattern is useful when a service wants to notify a recipient without having the recipient pinging the network periodically.

Operation Modes
There are two modes of operation for Discovery, Ad-Hoc mode and Managed mode.

  • In the Ad-Hoc mode a client sends the Probe/Resolve message over UDP multicast. The range of this message is limited to your subnet. Any service listening for such messages can pick it up and respond.
  • In Managed mode a client sends Probes and Resolves directly to the recipient, and it responds back with the endpoint metdata that matches.

Discovery Protocols

The WCF-Discovery product supports two versions of the WS-Discovery protocol. These include:

Currently the default is set to the WS-Discovery April 2005. Selecting the appropriate protocol is important depending on how you want to interop with other implementations of WS-Discovery. We'll cover protocols in depth later on.

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

Posted by anuragp | 1 Comments

Welcome to the Discovery Team’s Blog

This blog marks a first in a series to introduce you to what Discovery is all about. Cutting to the chase, the discovery functionality in .NET 4.0 provides means for making WCF services discoverable and for clients to locate such services. The technology is based on the WS-Discovery protocol, which is going through the standardization track at Oasis.  This means that the WCF-Discovery functionality is interoperable with lots of other implementations. 

There are a lot of benefits to using WCF-Discovery. With simple modifications to your client and service, you don’t need to hard code endpoints and as a result your services and clients become more robust. Clients don’t need to depend on configuration files for service locations, and admins don’t need to maintain such configuration information. Several problems associated with decoupling and distributed applications become much easier to solve with this technology. You can also have your service auto-configure itself; a service can find all the components it needs and be up and running without any effort.

We’ve made using discovery as easy as possible – there is extensive support for utilizing discovery through configuration and we also provide powerful programmatic tools so that you can leverage discovery to its full potential.

Through this blog, we’ll cover the depth of the WCF-Discovery functionality available to you such as: how to query for services, how to make services discoverable, how to use discovery through the asynchronous programming model, what the modes of operation for the protocol are, and how to build a Discovery Proxy service, to name a few topics.

The WCF-Discovery feature is now available as part of .NET 4.0 Beta1 release. You can download .NET 4.0 Beta1 and Visual Studio 2010 from http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx. The WCF-Discovery bits are part of System.ServiceModel.Discovery.dll assembly and are in System.ServiceModel.Discovery namespace.

Posted by anuragp | 1 Comments
Filed under: ,
 
Page view tracker