Visão geral da descoberta do WCF

As APIs de descoberta fornecem um modelo de programação unificado para a publicação dinâmica e a descoberta de serviços da Web usando o protocolo WS-Discovery. Essas APIs permitem que os serviços publiquem a si mesmos e que os clientes encontrem serviços publicados. Depois que um serviço se torna detetável, o serviço tem a capacidade de enviar mensagens de anúncio, bem como ouvir e responder a solicitações de descoberta. Os serviços detetáveis podem enviar mensagens Hello para anunciar a sua chegada a uma rede e mensagens Bye para anunciar a sua saída de uma rede. Para localizar um serviço, os clientes enviam uma Probe solicitação que contém critérios específicos, como tipo de contrato de serviço, palavras-chave e escopo na rede. Os serviços recebem a Probe solicitação e determinam se eles correspondem aos critérios. Se um serviço corresponder, ele responde enviando uma ProbeMatch mensagem de volta ao cliente com as informações necessárias para entrar em contato com o serviço. Os clientes também podem enviar Resolve solicitações que lhes permitem encontrar serviços que podem ter alterado seu endereço de ponto final. Os serviços correspondentes respondem às Resolve solicitações enviando uma ResolveMatch mensagem de volta ao cliente.

Modos Ad-Hoc e Gerenciado

A API de descoberta suporta dois modos diferentes: gerenciado e ad-hoc. No modo gerenciado, há um servidor centralizado chamado proxy de descoberta que mantém informações sobre os serviços disponíveis. O proxy de descoberta pode ser preenchido com informações sobre serviços de várias maneiras. Por exemplo, os serviços podem enviar mensagens de anúncio durante a inicialização para o proxy de descoberta ou o proxy pode ler dados de um banco de dados ou de um arquivo de configuração para determinar quais serviços estão disponíveis. A forma como o proxy de descoberta é preenchido depende completamente do desenvolvedor. Os clientes usam o proxy de descoberta para recuperar informações sobre os serviços disponíveis. Quando um cliente procura um serviço, ele envia uma Probe mensagem para o proxy de descoberta e o proxy determina se algum dos serviços que conhece corresponde ao serviço que o cliente está procurando. Se houver correspondências, o proxy de descoberta enviará uma ProbeMatch resposta de volta ao cliente. O cliente pode então entrar em contato diretamente com o serviço usando as informações de serviço retornadas do proxy. O princípio principal por trás do modo gerenciado é que as solicitações de descoberta são enviadas de maneira unicast para uma autoridade, o proxy de descoberta. O .NET Framework contém componentes-chave que permitem que você crie seu próprio proxy. Os clientes e serviços podem localizar o proxy por vários métodos:

  • O proxy pode responder a mensagens ad-hoc.

  • O proxy pode enviar uma mensagem de anúncio durante a inicialização.

  • Clientes e serviços podem ser escritos para procurar um ponto de extremidade específico bem conhecido.

No modo Ad-Hoc, não há um servidor centralizado. Todas as mensagens de descoberta, como anúncios de serviço e solicitações de clientes, são enviadas de forma multicast. Por padrão, o .NET Framework contém suporte para descoberta Ad-Hoc sobre o protocolo UDP. Por exemplo, se um serviço estiver configurado para enviar um anúncio Hello na inicialização, ele o enviará por um endereço multicast conhecido usando o protocolo UDP. Os clientes têm de ouvir ativamente estes anúncios e processá-los em conformidade. Quando um cliente envia uma Probe mensagem para um serviço, ela é enviada pela rede usando um protocolo multicast. Cada serviço que recebe a solicitação determina se ele corresponde aos critérios na Probe mensagem e responde diretamente ao cliente com uma ProbeMatch mensagem se o serviço corresponder aos critérios especificados na Probe mensagem.

Benefícios do uso do WCF Discovery

Como o WCF Discovery é implementado usando o protocolo WS-Discovery, ele é interoperável com outros clientes, serviços e proxies que também implementam o WS-Discovery. O WCF Discovery é criado com base nas APIs WCF existentes, o que facilita a adição da funcionalidade Discovery aos seus serviços e clientes existentes. A capacidade de descoberta do serviço pode ser facilmente adicionada por meio das definições de configuração do aplicativo. Além disso, o WCF Discovery também oferece suporte ao uso do protocolo de descoberta em outros transportes, como peer net, sobreposição de nomenclatura e HTTP. WCF Discovery fornece suporte para um modo gerenciado de operação onde um proxy de descoberta é usado. Isso pode reduzir o tráfego de rede, pois as mensagens são enviadas diretamente para o proxy de descoberta em vez de enviar mensagens multicast para toda a rede. O WCF Discovery também permite mais flexibilidade ao trabalhar com serviços Web. Por exemplo, você pode alterar o endereço de um serviço sem ter que reconfigurar o cliente ou o serviço. Quando um cliente precisa acessar o serviço, ele pode emitir uma Probe mensagem por meio de uma Find solicitação e esperar que o serviço responda com seu endereço atual. O WCF Discovery permite que um cliente pesquise um serviço com base em diferentes critérios, incluindo tipos de contrato, elementos de vinculação, namespace, escopo e palavras-chave ou números de versão. O WCF Discovery permite a descoberta de tempo de execução e tempo de design. Adicionar descoberta ao seu aplicativo pode ser usado para habilitar outros cenários, como tolerância a falhas e configuração automática.

Serviço de Publicação

Para tornar um serviço detetável, um ServiceDiscoveryBehavior deve ser adicionado ao host de serviço e um ponto de extremidade de descoberta deve ser adicionado para especificar onde ouvir mensagens de descoberta. O exemplo de código a seguir mostra como um serviço auto-hospedado pode ser modificado para torná-lo detetável.

Uri baseAddress = new Uri($"http://{System.Net.Dns.GetHostName()}:8000/discovery/scenarios/calculatorservice/{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();
}

Uma ServiceDiscoveryBehavior instância deve ser adicionada a uma descrição de serviço para que o serviço possa ser descoberto. Uma DiscoveryEndpoint instância deve ser adicionada ao host de serviço para informar ao serviço onde ouvir solicitações de descoberta. Neste exemplo, um UdpDiscoveryEndpoint (que é derivado de ) é adicionado para especificar que o serviço deve escutar solicitações de DiscoveryEndpointdescoberta no transporte multicast UDP. O UdpDiscoveryEndpoint é usado para descoberta Ad-Hoc porque todas as mensagens são enviadas de forma multicast.

Anúncio

Por padrão, a publicação do serviço não envia mensagens de anúncio. O serviço deve ser configurado para enviar mensagens de anúncio. Isso fornece flexibilidade adicional para os criadores de serviços, pois eles podem anunciar o serviço separadamente da escuta de mensagens de descoberta. O anúncio de serviço também pode ser usado como um mecanismo para registrar serviços com um proxy de descoberta ou outros registros de serviço. O código a seguir mostra como configurar um serviço para enviar mensagens de anúncio por meio de uma associação UDP.

Uri baseAddress = new Uri($"http://{System.Net.Dns.GetHostName()}:8000/discovery/scenarios/calculatorservice/{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(discoveryBehavior);

    // 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();
}

Deteção de Serviço

Um aplicativo cliente pode usar a DiscoveryClient classe para localizar serviços. O desenvolvedor cria uma instância da DiscoveryClient classe que passa em um ponto de extremidade de descoberta que especifica para onde enviar Probe ou Resolve mensagens. Em seguida, o cliente chama Find o que especifica os critérios de pesquisa dentro de uma FindCriteria instância. Se forem encontrados serviços correspondentes, Find devolve uma coleção de EndpointDiscoveryMetadata. O código a seguir mostra como chamar o Find método e, em seguida, conectar-se a um serviço descoberto.

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 =
            (Collection<EndpointDiscoveryMetadata>)discoveryClient.Find(new FindCriteria(typeof(ICalculator))).Endpoints;  
  
        discoveryClient.Close();  
  
        if (calculatorServices.Count == 0)  
        {  
            Console.WriteLine("\nNo services are found.");  
            return false;  
        }  
        else  
        {  
            serviceAddress = calculatorServices[0].Address;  
            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);  
    }
}  

Deteção e segurança em nível de mensagem

Ao usar a segurança de nível de mensagem, é necessário especificar um EndpointIdentity no ponto de extremidade de descoberta de serviço e uma correspondência EndpointIdentity no ponto de extremidade de descoberta do cliente. Para obter mais informações sobre segurança em nível de mensagem, consulte Segurança de mensagens.

Serviços de descoberta e hospedados na Web

Para que os serviços WCF sejam detetáveis, eles devem estar em execução. Os serviços WCF hospedados em IIS ou WAS não são executados até que o IIS/WAS receba uma mensagem vinculada ao serviço, portanto, eles não podem ser descobertos por padrão. Há duas opções para tornar os serviços hospedados na Web detetáveis:

  1. Usar o recurso Início Automático do Windows Server AppFabric

  2. Usar um proxy de descoberta para se comunicar em nome do serviço

O Windows Server AppFabric tem um recurso de Início Automático que permitirá que um serviço seja iniciado antes de receber quaisquer mensagens. Com esse conjunto de Início Automático, um serviço hospedado no IIS/WAS pode ser configurado para ser detetável. Para obter mais informações sobre o recurso Início Automático, consulte Recurso de Início Automático do Windows Server AppFabric. Além de ativar o recurso Início Automático, você deve configurar o serviço para descoberta. Para obter mais informações, consulte Como: Adicionar programaticamente a descoberta a um serviço WCF e Clienteconfigurando a descoberta em um arquivo de configuração.

Um proxy de descoberta pode ser usado para se comunicar em nome do serviço WCF quando o serviço não está em execução. O proxy pode escutar sondagens ou resolver mensagens e responder ao cliente. O cliente pode então enviar mensagens diretamente para o serviço. Quando o cliente envia uma mensagem para o serviço, ele será instanciado para responder à mensagem. Para obter mais informações sobre como implementar um proxy de descoberta, consulte Implementando um proxy de descoberta.

Nota

Para que o WCF Discovery funcione corretamente, todas as NICs (Network Interface Controller) devem ter apenas 1 endereço IP.