Compartir a través de


Procedimiento para agregar detectabilidad mediante programación a un cliente y un servicio de WCF

En este tema se explica cómo hacer que un servicio Windows Communication Foundation (WCF) sea detectable. Está basado en el ejemplo de hospedaje automático.

Para configurar el ejemplo de servicio de host automático existente repara para la detección

  1. Abra la solución de hospedaje automático en Visual Studio 2012. El ejemplo se encuentra en el directorio TechnologySamples\Basic\Service\Hosting\SelfHost.

  2. Agregue una referencia a System.ServiceModel.Discovery.dll al proyecto de servicio. Puede ver un mensaje de error que diga "System. "ServiceModel.Discovery.dll o una de sus dependencias necesita una versión posterior de .NET Framework a la que se especifica en el proyecto...". Si ve este mensaje, haga clic con el botón derecho en el Explorador de soluciones y seleccione Propiedades. En la ventana Propiedades del proyecto, asegúrese de que la Plataforma de destino es .NET Framework 4.6.1.

  3. Abra el archivo Service.cs y agregue la siguiente directiva using.

    using System.ServiceModel.Discovery;
    
  4. En el método Main(), dentro de la instrucción using, agregue una instancia ServiceDiscoveryBehavior al host de servicio.

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

    La clase ServiceDiscoveryBehavior especifica que el servicio al que se aplica es reconocible.

  5. Agregue UdpDiscoveryEndpoint al host de servicio justo después del código que agrega ServiceDiscoveryBehavior.

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

    Este código especifica que los mensajes de detección se deberían enviar al extremo de detección de UDP estándar.

Para crear una aplicación cliente que usa la detección para llamar al servicio

  1. Agregue a la solución una aplicación de consola nueva denominada DiscoveryClientApp.

  2. Agregue una referencia a System.ServiceModel.dll y System.ServiceModel.Discovery.dll.

  3. Copie los archivos GeneratedClient.cs y App.config del proyecto de cliente existente en el nuevo proyecto DiscoveryClientApp. Para ello, haga clic con el botón derecho en los archivos del Explorador de soluciones, seleccione Copiar y, a continuación, seleccione el proyecto DiscoveryClientApp, haga clic con el botón derecho y seleccione Pegar.

  4. Abra Program.cs.

  5. Añade las siguientes directivas using.

    using System.ServiceModel;
    using System.ServiceModel.Discovery;
    using Microsoft.ServiceModel.Samples;
    
  6. Agregue un método estático llamado FindCalculatorServiceAddress() a la clase Program.

    static EndpointAddress FindCalculatorServiceAddress()
    {
    }
    

    Este método usa la detección para buscar el servicio CalculatorService.

  7. Dentro del método FindCalculatorServiceAddress, cree una instancia DiscoveryClient nueva, pasando UdpDiscoveryEndpoint al constructor.

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

    Esto indica a WCF que la clase DiscoveryClient debe usar el punto de conexión de detección de UDP estándar para enviar y recibir mensajes de detección.

  8. En la línea siguiente, llame al método Find y especifique una instancia FindCriteria que contenga el contrato de servicios que desea buscar. En este caso, especifique ICalculator.

    // Find ICalculatorService endpoints
    FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(ICalculator)));
    
  9. Después de la llamada a Find, compruebe si hay por lo menos un servicio coincidente y devuelva la clase EndpointAddress del primer servicio coincidente. De lo contrario, devuelva null.

    if (findResponse.Endpoints.Count > 0)
    {
        return findResponse.Endpoints[0].Address;
    }
    else
    {
        return null;
    }
    
  10. Agregue un método estático llamado InvokeCalculatorService a la clase Program.

    static void InvokeCalculatorService(EndpointAddress endpointAddress)
    {
    }
    

    Este método utiliza la dirección del extremo devuelta de FindCalculatorServiceAddress para llamar al servicio de calculadora.

  11. Dentro del método InvokeCalculatorService, cree una instancia de la clase CalculatorServiceClient. Esta clase se define mediante el ejemplo de hospedaje automático. Se ha generado mediante Svcutil.exe.

    // Create a client
    CalculatorClient client = new CalculatorClient();
    
  12. En la línea siguiente, establezca la dirección del extremo del cliente en la dirección del extremo devuelta de FindCalculatorServiceAddress().

    // Connect to the discovered service endpoint
    client.Endpoint.Address = endpointAddress;
    
  13. Inmediatamente después del código del paso anterior, llame a los métodos expuestos por el servicio 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. Agregue el código al método Main() de la clase Program para llamar a FindCalculatorServiceAddress.

    public static void Main()
    {
        EndpointAddress endpointAddress = FindCalculatorServiceAddress();
    }
    
  15. En la línea siguiente, llame a InvokeCalculatorService() y pase la dirección del extremo devuelta de FindCalculatorServiceAddress().

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

Para probar la aplicación

  1. Abra un símbolo del sistema elevado y ejecute Service.exe.

  2. Abra un símbolo del sistema y ejecute Discoveryclientapp.exe.

  3. El resultado de service.exe debería ser el siguiente.

    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. El resultado de Discoveryclientapp.exe debería ser el siguiente.

    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.
    

Ejemplo

A continuación, se muestra una lista completa del código de este ejemplo. Dado que este código se basa en el ejemplo de hospedaje automático, solo se enumeran los archivos que cambian.

// 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 también