Información general de Detección de WCF

Las API de detección proporcionan un modelo de programación unificado para la detección y la publicación dinámica de servicios Web mediante el protocolo WS-Discovery. Estas API permiten a los servicios publicarse y a los clientes encontrar los servicios publicados. Una vez que un servicio es reconocible, tiene la capacidad de enviar mensajes de anuncio, así como realizar escuchas y responder a solicitudes de detección. Los servicios reconocibles pueden enviar mensajes de Hola para anunciar su llegada a la red, así como mensajes de Adiós para anunciar su salida de la red. Para encontrar un servicio, los clientes envían a una solicitud Probe que contiene criterios específicos, como tipos de contratos de servicios, palabras clave y ámbito de red. Los servicios reciben la solicitud Probe y determinan si coinciden con los criterios. Si un servicio coincide, responde devolviendo un mensaje ProbeMatch al cliente con la información necesaria para ponerse en contacto con el servicio. Los clientes también pueden enviar solicitudes Resolve para buscar servicios que pueden haber cambiado la dirección de extremo. Los servicios coincidentes responden a las solicitudes Resolve devolviendo un mensaje ResolveMatch al cliente.

Modos ad hoc y administrados

Las API de detección admiten dos modos diferentes: administrado y ad hoc. En el modo administrado, hay un servidor centralizado, denominado proxy de detección, que contiene información sobre los servicios disponibles. El proxy de detección se puede rellenar con información sobre servicios de diferentes maneras. Por ejemplo, los servicios pueden enviar mensajes de anuncio durante el inicio al proxy de detección, o el proxy puede leer datos de una base de datos o un archivo de configuración para determinar qué servicios están disponibles. El modo en que se rellena el proxy de detección depende por completo del desarrollador. Los clientes utilizan el proxy de detección para recuperar información sobre servicios disponibles. Cuando un cliente busca un servicio, envía un mensaje Probe al proxy de detección y el proxy determina si alguno de los servicios que conoce coincide con el servicio que busca el cliente. Si hay coincidencias, el proxy de detección devuelve una respuesta ProbeMatch al cliente. A continuación, el cliente puede ponerse en contacto con el servicio de forma directa a través de la información de servicio devuelta por el proxy. El principio básico del modo administrado es que las solicitudes de detección se envían en modo de unidifusión a una autoridad, el proxy de detección. El sistema .NET Framework contiene componentes clave que le permiten compilar su propio proxy. Los clientes y los servicios pueden buscar el proxy a través de varios métodos:

  • El proxy puede responder a los mensajes ad hoc.

  • El proxy puede enviar un mensaje de anuncio durante el inicio.

  • Los clientes y los servicios se pueden escribir para buscar un extremo conocido concreto.

En modo ad hoc, no hay ningún servidor centralizado. Todos los mensajes de detección, como anuncios de servicio y solicitudes de clientes, se envían en modo de multidifusión. De forma predeterminada, .NET Framework contiene soporte para la detección ad hoc en el protocolo UDP. Por ejemplo, si un servicio se configura para enviar un anuncio de Hola durante el inicio, lo manda en una dirección de multidifusión conocida mediante el protocolo UDP. Los clientes tienen que realizar escuchas activas de estos anuncios y procesarlos de forma correspondiente. Cuando un cliente envía un mensaje Probe para un servicio, se envía a través de la red mediante un protocolo de multidifusión. Cada servicio que recibe la solicitud determina si ésta coincide con los criterios del mensaje Probe y responde directamente al cliente con un mensaje ProbeMatch si el servicio coincide con los criterios especificados en el mensaje Probe.

Ventajas de utilizar la Detección de WCF

Dado que la Detección de WCF se implementa mediante el protocolo WS-Discovery, es interoperable con otros clientes, servicios y proxys que también implementan WS-Discovery. La Detección de WCF se compila en las API de WCF existentes, lo que facilita la adición de la funcionalidad de detección a los servicios y clientes existentes. La detectabilidad del servicio se puede agregar con facilidad a través de la configuración de la aplicación. Además, la Detección de WCF también permite usar el protocolo de detección en otros transportes como redes del mismo nivel, superposiciones de nomenclatura y HTTP. La Detección de WCF proporciona soporte para un modo administrado de operación en el que se usa un proxy de detección. Esto puede reducir el tráfico de red, ya que los mensajes se envían directamente al proxy de detección en lugar de enviar mensajes de multidifusión a toda la red. La Detección de WCF también permite una mayor flexibilidad al trabajar con servicios Web. Por ejemplo, puede cambiar la dirección de un servicio sin tener que reconfigurar ni el cliente ni el servicio. Cuando un cliente debe acceder al servicio, puede emitir un mensaje Probe a través de una solicitud Find y esperar a que el servicio responda con su dirección actual. La Detección de WCF permite a un cliente buscar un servicio en función de diversos criterios, incluidos tipos de contrato, elementos de enlace, espacio de nombres, ámbito y palabras clave o números de versión. La Detección de WCF habilita la detección de diseño y de tiempo de ejecución. La adición de la detección a la aplicación se puede usar para habilitar otros escenarios como tolerancia a errores y configuración automática.

Publicación de servicios

Para hacer un servicio reconocible, debe agregarse ServiceDiscoveryBehavior al host de servicio, así como un extremo de detección para especificar dónde realizar escuchas para los mensajes de detección. El siguiente ejemplo de código muestra cómo se puede modificar un servicio auto-hospedado para hacerlo reconocible.

Uri baseAddress = new Uri(string.Format("http://{0}:8000/discovery/scenarios/calculatorservice/{1}/",
        System.Net.Dns.GetHostName(), Guid.NewGuid().ToString()));

// Create a ServiceHost for the CalculatorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress))
{
    // add calculator endpoint
    serviceHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), string.Empty);

    // ** DISCOVERY ** //
    // make the service discoverable by adding the discovery behavior
    serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());

    // ** DISCOVERY ** //
    // add the discovery endpoint that specifies where to publish the services
    serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
    
    // Open the ServiceHost to create listeners and start listening for messages.
    serviceHost.Open();

    // The service can now be accessed.
    Console.WriteLine("Press <ENTER> to terminate service.");
    Console.ReadLine();
}

Debe agregarse una instancia ServiceDiscoveryBehavior a una descripción de servicio para que el servicio sea reconocible. Debe agregarse una instancia DiscoveryEndpoint al host de servicio para indicar al servicio dónde realizar escuchas para las solicitudes de detección. En este ejemplo, se agrega UdpDiscoveryEndpoint (que se deriva de DiscoveryEndpoint) para especificar que el servicio debe realizar escuchas de solicitudes de detección en el transporte multidifusión de UDP. UdpDiscoveryEndpoint se utiliza para la detección ad hoc porque todos los mensajes se envían en modo de multidifusión.

Anuncio

De forma predeterminada, la publicación del servicio no manda mensajes de anuncio. El servicio se debe configurar para mandar mensajes de anuncio. Esto proporciona una flexibilidad adicional a los escritores del servicio, ya que pueden anunciar el servicio de forma independiente de la realización de escuchas de mensajes de detección. El anuncio de servicio también se puede usar como mecanismo de registro de los servicios con un proxy de detección u otros registros del servicio. El siguiente código muestra cómo configurar un servicio para enviar mensajes de anuncio en un enlace de UDP.

Uri baseAddress = new Uri(string.Format("http://{0}:8000/discovery/scenarios/calculatorservice/{1}/",
        System.Net.Dns.GetHostName(), Guid.NewGuid().ToString()));

// Create a ServiceHost for the CalculatorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress))
{
    // add calculator endpoint
    serviceHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), string.Empty);

    // ** DISCOVERY ** //
    // make the service discoverable by adding the discovery behavior
    ServiceDiscoveryBehavior discoveryBehavior = new ServiceDiscoveryBehavior();
    serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());

    // send announcements on UDP multicast transport
    discoveryBehavior.AnnouncementEndpoints.Add(
      new UdpAnnouncementEndpoint());
    
    // ** DISCOVERY ** //
    // add the discovery endpoint that specifies where to publish the services
    serviceHost.Description.Endpoints.Add(new UdpDiscoveryEndpoint());
    
    // Open the ServiceHost to create listeners and start listening for messages.
    serviceHost.Open();

    // The service can now be accessed.
    Console.WriteLine("Press <ENTER> to terminate service.");
    Console.ReadLine();
}

Detección de servicios

Una aplicación cliente puede usar la clase DiscoveryClient para buscar servicios. El desarrollador crea una instancia de la clase DiscoveryClient que pasa un extremo de detección que especifica dónde se deben enviar los mensajes Probe o Resolve. A continuación, el cliente llama a Find, que especifica los criterios de búsqueda dentro de una instancia FindCriteria. Si se encuentran servicios correspondientes, Find devuelve una recopilación de EndpointDiscoveryMetadata. El siguiente código muestra cómo llamar al método Find y, a continuación, conectarse a un servicio detectado.

class Client
{
    static EndpointAddress serviceAddress;

    static void Main()
    {
        if (FindService()) InvokeService();
    }

    // ** DISCOVERY ** //
    static bool FindService()
    {
        Console.WriteLine("\nFinding Calculator Service ..");
        DiscoveryClient discoveryClient = 
            new DiscoveryClient(new UdpDiscoveryEndpoint());

        Collection<EndpointDiscoveryMetadata> calculatorServices = 
            discoveryClient.Find(new FindCriteria(typeof(ICalculator)));

        discoveryClient.Close();

        if (calculatorServices.Count == 0)
        {
            Console.WriteLine("\nNo services are found.");
            return false;
        }
        else
        {
            serviceAddress = calculatorServices[0].EndpointAddress;
            return true;
        }
    }

    static void InvokeService()
    {
        Console.WriteLine("\nInvoking Calculator Service at {0}\n", serviceAddress);

        // Create a client
        CalculatorClient client = new CalculatorClient();
        client.Endpoint.Address = serviceAddress;
        client.Add(10,3);
}

Detección y seguridad de nivel de mensaje

Al utilizar la seguridad de nivel de mensaje, es necesario especificar una clase EndpointIdentity en el extremo de detección de servicio, y una clase EndpointIdentity coincidente en el extremo de detección de cliente. Para obtener más información sobre la seguridad de nivel de mensaje, vea Seguridad de los mensajes en WCF.