Compartir a través de


Cómo: Agregar detectabilidad mediante programación a un cliente y un servicio de WCF

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

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

  1. Abra la solución de host automático en Visual Studio 2010. 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 dice "System. ServiceModel.Discovery.dll, o alguna de sus dependencias, requiere una versión de .NET Framework posterior a la especificada en el proyecto...". Si ve este mensaje, haga clic con el botón secundario en el Explorador de soluciones y seleccione Propiedades. En la ventana Propiedades del proyecto, asegúrese de que la Versión de .NET Framework de destino es .NET Framework versión 4.

  3. Abra el archivo Service.cs y agregue la siguiente instrucción 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 secundario en los archivos del Explorador de soluciones, seleccione Copiar y, a continuación, seleccione el proyecto DiscoveryClientApp, haga clic con el botón secundario y seleccione Pegar.

  4. Abra Program.cs.

  5. Agregue las instrucciones using siguientes.

    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 debería usar el extremo 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 host 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.

    Suma recibida(100,15.99)
    Resultado: 115.99
    Resta recibida(100,15.99)
    Resultado: 84.01
    Multiplicación recibida(100,15.99)
    Resultado: 1599
    División recibida(100,15.99)
    Resultado: 6.25390869293308
  1. El resultado de Discoveryclientapp.exe debería ser el siguiente.
    Invocar CalculatorService en https://localhost:8000/ServiceModelSamples/service
    Sumar (100,15.99) = 115.99
    Restar (100,15.99) = 84.01
    Multiplicar (100,15.99) = 1599
    Dividir (100,15.99) = 6.25390869293308

    Presione &lt;ENTRAR&gt; para salir.

Ejemplo

A continuación, se muestra una lista completa del código de este ejemplo. Dado que este código está basado en el ejemplo de host automático, solo se incluyen en la lista los archivos modificados. Para obtener más información sobre el ejemplo de host automático, vea las Instrucciones de configuración.

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

Vea también

Conceptos

Información general de Detección de WCF
Modelo de objetos de Detección de WCF