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
Abra la solución de host automático en Visual Studio 2010. El ejemplo se encuentra en el directorio TechnologySamples\Basic\Service\Hosting\SelfHost.
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.Abra el archivo Service.cs y agregue la siguiente instrucción
using
.using System.ServiceModel.Discovery;
En el método
Main()
, dentro de la instrucciónusing
, 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.
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
Agregue a la solución una aplicación de consola nueva denominada
DiscoveryClientApp
.Agregue una referencia a
System.ServiceModel.dll
ySystem.ServiceModel.Discovery.dll
.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.
Abra Program.cs.
Agregue las instrucciones
using
siguientes.using System.ServiceModel; using System.ServiceModel.Discovery; using Microsoft.ServiceModel.Samples;
Agregue un método estático llamado
FindCalculatorServiceAddress()
a la claseProgram
.static EndpointAddress FindCalculatorServiceAddress() { }
Este método usa la detección para buscar el servicio
CalculatorService
.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.
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)));
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; }
Agregue un método estático llamado
InvokeCalculatorService
a la claseProgram
.static void InvokeCalculatorService(EndpointAddress endpointAddress) { }
Este método utiliza la dirección del extremo devuelta de
FindCalculatorServiceAddress
para llamar al servicio de calculadora.Dentro del método
InvokeCalculatorService
, cree una instancia de la claseCalculatorServiceClient
. Esta clase se define mediante el ejemplo de host automático. Se ha generado mediante Svcutil.exe.// Create a client CalculatorClient client = new CalculatorClient();
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;
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();
Agregue el código al método
Main()
de la claseProgram
para llamar aFindCalculatorServiceAddress
.public static void Main() { EndpointAddress endpointAddress = FindCalculatorServiceAddress(); }
En la línea siguiente, llame a
InvokeCalculatorService()
y pase la dirección del extremo devuelta deFindCalculatorServiceAddress()
.if (endpointAddress != null) { InvokeCalculatorService(endpointAddress); } Console.WriteLine("Press <ENTER> to exit."); Console.ReadLine();
Para probar la aplicación
Abra un símbolo del sistema elevado y ejecute Service.exe.
Abra un símbolo del sistema y ejecute Discoveryclientapp.exe.
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
- 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 <ENTRAR> 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