Procédure : ajouter la détectabilité par programme à un service et un client WCF
Cette rubrique explique comment rendre un service Windows Communication Foundation (WCF) détectable. Elle s'appuie sur l'exemple Self-Host.
Pour configurer l'exemple existant de service Self-Host pour la découverte
Ouvrez la solution Self-Host dans Visual Studio 2010. L'exemple se trouve dans le répertoire TechnologySamples\Basic\Service\Hosting\SelfHost.
Ajoutez au projet du service une référence à
System.ServiceModel.Discovery.dll
. Un message d'erreur s'affiche éventuellement, indiquant « System. ServiceModel.Discovery.dll ou l'une de ses dépendances requiert une version ultérieure du .NET Framework à celle spécifiée dans le projet... ». Si ce message s'affiche, cliquez avec le bouton droit sur le projet dans l'Explorateur de solutions et choisissez Propriétés. Dans la fenêtre Propriétés du projet, assurez-vous que la version cible de .Net Framework est .NET Framework version 4.Ouvrez le fichier Service.cs et ajoutez l'instruction
using
suivante.using System.ServiceModel.Discovery;
Dans la méthode
Main()
, à l'intérieur de l'instructionusing
, ajoutez une instance ServiceDiscoveryBehavior à l'hôte du service.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()); // ... } }
L'instance ServiceDiscoveryBehavior spécifie que le service auquel elle s'applique est détectable.
Ajoutez un objet UdpDiscoveryEndpoint à l'hôte du service, juste après le code qui ajoute l'instance ServiceDiscoveryBehavior.
// Add ServiceDiscoveryBehavior serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior()); // Add a UdpDiscoveryEndpoint serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
Ce code spécifie que les messages de découverte doivent être envoyés au point de terminaison de découverte UDP standard.
Pour créer une application cliente utilisant la découverte pour appeler le service
Ajoutez à la solution une nouvelle application console nommée
DiscoveryClientApp
.Ajoutez une référence à
System.ServiceModel.dll
et àSystem.ServiceModel.Discovery.dll
.Copiez les fichiers GeneratedClient.cs et App.config du projet client existant dans le nouveau projet DiscoveryClientApp. Pour ce faire, cliquez avec le bouton droit sur les fichiers dans l'Explorateur de solutions, sélectionnez Copier, puis sélectionnez le projet DiscoveryClientApp, cliquez avec le bouton droit et sélectionnez Coller.
Ouvrez Program.cs.
Ajoutez les instructions
using
suivantes.using System.ServiceModel; using System.ServiceModel.Discovery; using Microsoft.ServiceModel.Samples;
Ajoutez une méthode statique nommée
FindCalculatorServiceAddress()
à la classeProgram
.static EndpointAddress FindCalculatorServiceAddress() { }
Cette méthode utilise la découverte pour rechercher le service
CalculatorService
.À l'intérieur de la méthode
FindCalculatorServiceAddress
, créez une instance DiscoveryClient, en transmettant un objet UdpDiscoveryEndpoint au constructeur.static EndpointAddress FindCalculatorServiceAddress() { // Create DiscoveryClient DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint()); }
Cela indique à WCF que la classe DiscoveryClient doit utiliser le point de terminaison de découverte UDP standard pour envoyer et recevoir des messages de découverte.
Sur la ligne suivante, appelez la méthode Find et spécifiez une instance FindCriteria qui contient le contrat de service que vous souhaitez rechercher. Le contrat à spécifier dans le cas présent est
ICalculator
.// Find ICalculatorService endpoints FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(ICalculator)));
Après l'appel à la méthode Find, vérifiez s'il existe au moins un service correspondant et retournez l'objet EndpointAddress du premier service correspondant. Autrement, retournez une valeur Null.
if (findResponse.Endpoints.Count > 0) { return findResponse.Endpoints[0].Address; } else { return null; }
Ajoutez une méthode statique nommée
InvokeCalculatorService
à la classeProgram
.static void InvokeCalculatorService(EndpointAddress endpointAddress) { }
Cette méthode utilise l'adresse du point de terminaison retournée par l'objet
FindCalculatorServiceAddress
pour appeler le service de calculatrice.À l'intérieur de la méthode
InvokeCalculatorService
, créez une instance de la classeCalculatorServiceClient
. Cette classe est définie par l'exemple Self-Host. Elle a été générée à l'aide de Svcutil.exe.// Create a client CalculatorClient client = new CalculatorClient();
Sur la ligne suivante, définissez l'adresse du point de terminaison du client sur l'adresse du point de terminaison retournée par l'objet
FindCalculatorServiceAddress()
.// Connect to the discovered service endpoint client.Endpoint.Address = endpointAddress;
Immédiatement après le code de l'étape précédente, appelez les méthodes exposées par le service de calculatrice.
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();
Ajoutez un code à la méthode
Main()
dans la classeProgram
pour appelerFindCalculatorServiceAddress
.public static void Main() { EndpointAddress endpointAddress = FindCalculatorServiceAddress(); }
Sur la ligne suivante, appelez
InvokeCalculatorService()
et passez l'adresse du point de terminaison retournée parFindCalculatorServiceAddress()
.if (endpointAddress != null) { InvokeCalculatorService(endpointAddress); } Console.WriteLine("Press <ENTER> to exit."); Console.ReadLine();
Pour tester l'application
Ouvrez une invite de commandes avec élévation de privilèges et exécutez Service.exe.
Ouvrez une invite de commandes et exécutez Discoveryclientapp.exe.
La sortie de service.exe doit ressembler à la sortie suivante.
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
- La sortie de Discoveryclientapp.exe doit ressembler à la sortie suivante.
Invoking CalculatorService at https://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.
Exemple
L'intégralité du code utilisé dans cet exemple est présentée ci-dessous. Comme ce code s'appuie sur l'exemple Self-Host, seuls les fichiers modifiés sont répertoriés. Pour plus d'informations sur le sujet suivant l'exemple Self-Host, consultez Setup Instructions (en anglais).
// 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();
}
}
}
Voir aussi
Concepts
Vue d'ensemble de la découverte WCF
Modèle objet de découverte WCF