Partilhar via


Como: Adicionar programaticamente a capacidade de descoberta a um serviço WCF e cliente

Este tópico explica como tornar um serviço WCF (Windows Communication Foundation) detetável. Baseia-se no exemplo Self-Host .

Para configurar o exemplo de serviço Self-Host existente para Descoberta

  1. Abra a solução Self-Host no Visual Studio 2012. O exemplo está localizado no diretório TechnologySamples\Basic\Service\Hosting\SelfHost.

  2. Adicione uma referência ao System.ServiceModel.Discovery.dll projeto de serviço. Poderá ver uma mensagem de erro a dizer "Sistema. ServiceModel.Discovery.dll ou uma de suas dependências requer uma versão posterior do .NET Framework do que a especificada no projeto ..." Se você vir essa mensagem, clique com o botão direito do mouse no projeto no Gerenciador de Soluções e escolha Propriedades. Na janela Propriedades do projeto, certifique-se de que o Target Framework é .NET Framework 4.6.1.

  3. Abra o arquivo Service.cs e adicione a seguinte using diretiva.

    using System.ServiceModel.Discovery;
    
  4. Main() No método, dentro da using instrução, adicione uma ServiceDiscoveryBehavior instância ao host de serviço.

    public static void Main()
    {
        // Create a ServiceHost for the CalculatorService type.
        using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService)))
        {
            // Add a ServiceDiscoveryBehavior
            serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
    
            // ...
        }
    }
    

    O ServiceDiscoveryBehavior especifica que o serviço ao qual ele é aplicado é detetável.

  5. Adicione um UdpDiscoveryEndpoint ao host de serviço logo após o código que adiciona o ServiceDiscoveryBehavior.

    // Add ServiceDiscoveryBehavior
    serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
    
    // Add a UdpDiscoveryEndpoint
    serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
    

    Esse código especifica que as mensagens de descoberta devem ser enviadas para o ponto de extremidade de descoberta UDP padrão.

Para criar um aplicativo cliente que usa a descoberta para chamar o serviço

  1. Adicione um novo aplicativo de console à solução chamada DiscoveryClientApp.

  2. Adicionar uma referência a System.ServiceModel.dll e System.ServiceModel.Discovery.dll

  3. Copie os arquivos GeneratedClient.cs e App.config do projeto cliente existente para o novo projeto DiscoveryClientApp. Para fazer isso, clique com o botão direito do mouse nos arquivos no Gerenciador de Soluções, selecione Copiar e, em seguida, selecione o projeto DiscoveryClientApp, clique com o botão direito do mouse e selecione Colar.

  4. Abra o Program.cs.

  5. Aditar as seguintes using diretivas.

    using System.ServiceModel;
    using System.ServiceModel.Discovery;
    using Microsoft.ServiceModel.Samples;
    
  6. Adicione um método estático chamado FindCalculatorServiceAddress() à Program classe.

    static EndpointAddress FindCalculatorServiceAddress()
    {
    }
    

    Este método utiliza a deteção para procurar o CalculatorService serviço.

  7. Dentro do FindCalculatorServiceAddress método, crie uma nova DiscoveryClient instância, passando em a UdpDiscoveryEndpoint para o construtor.

    static EndpointAddress FindCalculatorServiceAddress()
    {
        // Create DiscoveryClient
        DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
    }
    

    Isso informa ao WCF que a DiscoveryClient classe deve usar o ponto de extremidade de descoberta UDP padrão para enviar e receber mensagens de descoberta.

  8. Na próxima linha, chame o Find método e especifique uma FindCriteria instância que contenha o contrato de serviço que você deseja pesquisar. Nesse caso, especifique ICalculator.

    // Find ICalculatorService endpoints
    FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(ICalculator)));
    
  9. Após a chamada para Find, verifique se há pelo menos um serviço correspondente e retorne o EndpointAddress do primeiro serviço correspondente. Caso contrário, retorne.null

    if (findResponse.Endpoints.Count > 0)
    {
        return findResponse.Endpoints[0].Address;
    }
    else
    {
        return null;
    }
    
  10. Adicione um método estático nomeado InvokeCalculatorService à Program classe.

    static void InvokeCalculatorService(EndpointAddress endpointAddress)
    {
    }
    

    Esse método usa o endereço do ponto de extremidade retornado para chamar o serviço de FindCalculatorServiceAddress calculadora.

  11. Dentro do InvokeCalculatorService método, crie uma instância da CalculatorServiceClient classe. Essa classe é definida pelo exemplo Self-Host . Foi gerado usando Svcutil.exe.

    // Create a client
    CalculatorClient client = new CalculatorClient();
    
  12. Na próxima linha, defina o endereço do ponto de extremidade do cliente como o endereço do ponto de extremidade retornado do FindCalculatorServiceAddress().

    // Connect to the discovered service endpoint
    client.Endpoint.Address = endpointAddress;
    
  13. Imediatamente após o código da etapa anterior, chame os métodos expostos pelo serviço de calculadora.

    Console.WriteLine("Invoking CalculatorService at {0}", endpointAddress);
    
    double value1 = 100.00D;
    double value2 = 15.99D;
    
    // Call the Add service operation.
    double result = client.Add(value1, value2);
    Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
    
    // Call the Subtract service operation.
    result = client.Subtract(value1, value2);
    Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);
    
    // Call the Multiply service operation.
    result = client.Multiply(value1, value2);
    Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
    
    // Call the Divide service operation.
    result = client.Divide(value1, value2);
    Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
    Console.WriteLine();
    
    //Closing the client gracefully closes the connection and cleans up resources
    client.Close();
    
  14. Adicione código Main() ao método na Program classe para chamar FindCalculatorServiceAddress.

    public static void Main()
    {
        EndpointAddress endpointAddress = FindCalculatorServiceAddress();
    }
    
  15. Na próxima linha, chame o InvokeCalculatorService() e passe o endereço do ponto de extremidade retornado de FindCalculatorServiceAddress().

    if (endpointAddress != null)
    {
        InvokeCalculatorService(endpointAddress);
    }
    
    Console.WriteLine("Press <ENTER> to exit.");
    Console.ReadLine();
    

Para testar a aplicação

  1. Abra um prompt de comando elevado e execute Service.exe.

  2. Abra um prompt de comando e execute Discoveryclientapp.exe.

  3. A saída do service.exe deve ser semelhante à saída a seguir.

    Received Add(100,15.99)
    Return: 115.99
    Received Subtract(100,15.99)
    Return: 84.01
    Received Multiply(100,15.99)
    Return: 1599
    Received Divide(100,15.99)
    Return: 6.25390869293308
    
  4. A saída do Discoveryclientapp.exe deve ser semelhante à saída a seguir.

    Invoking CalculatorService at http://localhost:8000/ServiceModelSamples/service
    Add(100,15.99) = 115.99
    Subtract(100,15.99) = 84.01
    Multiply(100,15.99) = 1599
    Divide(100,15.99) = 6.25390869293308
    
    Press <ENTER> to exit.
    

Exemplo

A seguir está uma lista do código para este exemplo. Como esse código é baseado no exemplo Self-Host , somente os arquivos que são alterados são listados.

// Service.cs
using System;
using System.Configuration;
using System.ServiceModel;
using System.ServiceModel.Discovery;

namespace Microsoft.ServiceModel.Samples
{
    // See SelfHost sample for service contract and implementation
    // ...

        // Host the service within this EXE console application.
        public static void Main()
        {
            // Create a ServiceHost for the CalculatorService type.
            using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService)))
            {
                // Add the ServiceDiscoveryBehavior to make the service discoverable
                serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
                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("The service is ready.");
                Console.WriteLine("Press <ENTER> to terminate service.");
                Console.WriteLine();
                Console.ReadLine();
            }
        }
    }
}
// Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Discovery;
using Microsoft.ServiceModel.Samples;
using System.Text;

namespace DiscoveryClientApp
{
    class Program
    {
        static EndpointAddress FindCalculatorServiceAddress()
        {
            // Create DiscoveryClient
            DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());

            // Find ICalculatorService endpoints
            FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(ICalculator)));

            if (findResponse.Endpoints.Count > 0)
            {
                return findResponse.Endpoints[0].Address;
            }
            else
            {
                return null;
            }
        }

        static void InvokeCalculatorService(EndpointAddress endpointAddress)
        {
            // Create a client
            CalculatorClient client = new CalculatorClient();

            // Connect to the discovered service endpoint
            client.Endpoint.Address = endpointAddress;

            Console.WriteLine("Invoking CalculatorService at {0}", endpointAddress);

            double value1 = 100.00D;
            double value2 = 15.99D;

            // Call the Add service operation.
            double result = client.Add(value1, value2);
            Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

            // Call the Subtract service operation.
            result = client.Subtract(value1, value2);
            Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);

            // Call the Multiply service operation.
            result = client.Multiply(value1, value2);
            Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

            // Call the Divide service operation.
            result = client.Divide(value1, value2);
            Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
            Console.WriteLine();

            //Closing the client gracefully closes the connection and cleans up resources
            client.Close();
        }
        static void Main(string[] args)
        {
            EndpointAddress endpointAddress = FindCalculatorServiceAddress();

            if (endpointAddress != null)
            {
                InvokeCalculatorService(endpointAddress);
            }

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

        }
    }
}

Consulte também