Compartilhar via


Visão geral de 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 Web usando o protocolo WS-Discovery. Essas APIs permitem que os serviços publiquem a si mesmos e aos clientes para encontrar serviços publicados. Depois que um serviço é descoberto, o serviço tem a capacidade de enviar mensagens de anúncio, bem como escutar e responder às solicitações de descoberta. Os serviços detectáveis podem enviar mensagens hello para anunciar sua chegada em uma rede e mensagens de Bye para anunciar sua saída de uma rede. Para localizar um serviço, os clientes enviam uma solicitação Probe 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 solicitação Probe e determinam se correspondem aos critérios. Se um serviço corresponder, ele responderá enviando uma mensagem ProbeMatch de volta ao cliente com as informações necessárias para entrar em contato com o serviço. Os clientes também podem enviar solicitações Resolve que permitem que eles encontrem serviços que podem ter alterado o endereço do ponto de extremidade. Os serviços correspondentes respondem às solicitações Resolve enviando uma mensagem ResolveMatch de volta para o cliente.

Modos Ad-Hoc e Gerenciados

A API de Descoberta dá suporte a dois modos diferentes: Gerenciado e Ad-Hoc. No modo Gerenciado, há um servidor centralizado chamado proxy de descoberta que mantém informações sobre 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 é completamente de acordo com o desenvolvedor. Os clientes usam o proxy de descoberta para recuperar informações sobre os serviços disponíveis. Quando um cliente pesquisa um serviço, ele envia uma mensagem Probe para o proxy de descoberta e o proxy determina se qualquer um dos serviços que ele sabe sobre corresponder ao serviço que o cliente está procurando. Se houver correspondências, o proxy de descoberta envia uma resposta ProbeMatch de volta ao cliente. Em seguida, o cliente pode entrar em contato diretamente com o serviço usando as informações de serviço retornadas do proxy. O princípio-chave 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 criar seu próprio proxy. 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 gravados para procurar um ponto de extremidade conhecido específico.

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

Benefícios de usar a Descoberta do WCF

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

Publicação de serviço

Para tornar um serviço detectável, um ServiceDiscoveryBehavior deve ser adicionado ao host de serviço e um ponto de extremidade de descoberta deve ser adicionado para especificar onde escutar mensagens de descoberta. O exemplo de código a seguir mostra como um serviço auto-hospedado pode ser modificado para torná-lo detectá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 instância ServiceDiscoveryBehavior deve ser adicionada a uma descrição de serviço para que o serviço seja detectável. Uma instância DiscoveryEndpoint deve ser adicionada ao host de serviço para informar ao serviço onde escutar solicitações de descoberta. Neste exemplo, um UdpDiscoveryEndpoint (que é derivado de DiscoveryEndpoint) é adicionado para especificar que o serviço deve escutar solicitações de descoberta pelo transporte multicast UDP. O UdpDiscoveryEndpoint é usado para a descoberta do Ad-Hoc porque todas as mensagens são enviadas de forma multicast.

Anúncio

Por padrão, a publicação de 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 gravadores de serviço porque 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();
}

Descoberta de Serviços

Um aplicativo cliente pode usar a classe DiscoveryClient para localizar serviços. O desenvolvedor cria uma instância da classe DiscoveryClient que passa em um ponto de extremidade de descoberta que especifica para onde enviar as mensagens Probe ou Resolve. Em seguida, o cliente chama Find que especifica critérios de pesquisa em uma instância FindCriteria. Se os serviços correspondentes forem encontrados, Find retornará uma coleção de EndpointDiscoveryMetadata. O código a seguir mostra como chamar o método Find 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);  
    }
}  

Segurança de nível de descoberta e mensagem

Ao usar a segurança no nível da 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 no nível da mensagem, consulte Segurança de Mensagem.

Serviços de Descoberta e Hospedados na Web

Para que os serviços WCF sejam detectá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 associada 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 detectáveis:

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

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

O AppFabric do Windows Server tem um recurso de Início Automático que permitirá que um serviço seja iniciado antes de receber mensagens. Com esse Início Automático definido, um serviço hospedado em IIS/WAS pode ser configurado para ser detectável. Para obter mais informações sobre o recurso de Início Automático, consulte Recurso de Início Automático do AppFabric do Windows Server. Além de ativar o recurso de 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 ao 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 estiver em execução. O proxy pode escutar mensagens de investigação ou resolução e responder ao cliente. Em seguida, o cliente pode 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.

Observação

Para que a Descoberta do WCF funcione corretamente, todas as NICs (Controlador de Interface de Rede) devem ter apenas 1 endereço IP.