Instrukcje: Programowe dodawanie możliwości odnajdywania do usługi i klienta WCF
W tym temacie opisano sposób odnajdywania usługi Windows Communication Foundation (WCF). Jest on oparty na przykładzie Self-Host .
Aby skonfigurować istniejący przykład samoobsługi na potrzeby odnajdywania
Otwórz rozwiązanie self-host w programie Visual Studio 2012. Przykład znajduje się w katalogu TechnologySamples\Basic\Service\Hosting\SelfHost.
Dodaj odwołanie do
System.ServiceModel.Discovery.dll
projektu usługi. Może zostać wyświetlony komunikat o błędzie z komunikatem "System. ServiceModel.Discovery.dll lub jedną z jego zależności wymaga nowszej wersji programu .NET Framework niż określona w projekcie ..." Jeśli zostanie wyświetlony ten komunikat, kliknij prawym przyciskiem myszy projekt w Eksplorator rozwiązań i wybierz polecenie Właściwości. W oknie Właściwości projektu upewnij się, że platforma docelowa to .NET Framework 4.6.1.Otwórz plik Service.cs i dodaj następującą
using
dyrektywę.using System.ServiceModel.Discovery;
W metodzie
Main()
wewnątrz instrukcjiusing
dodaj ServiceDiscoveryBehavior wystąpienie do hosta usługi.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()); // ... } }
Określa ServiceDiscoveryBehavior , że usługa, do którego jest stosowana, jest wykrywalna.
Dodaj element UdpDiscoveryEndpoint do hosta usługi bezpośrednio po kodzie, który dodaje element ServiceDiscoveryBehavior.
// Add ServiceDiscoveryBehavior serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior()); // Add a UdpDiscoveryEndpoint serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
Ten kod określa, że komunikaty odnajdywania powinny być wysyłane do standardowego punktu końcowego odnajdywania UDP.
Aby utworzyć aplikację kliencką korzystającą z odnajdywania w celu wywołania usługi
Dodaj nową aplikację konsolową do rozwiązania o nazwie
DiscoveryClientApp
.Dodawanie odwołania do i
System.ServiceModel.dll
System.ServiceModel.Discovery.dll
Skopiuj pliki GeneratedClient.cs i App.config z istniejącego projektu klienta do nowego projektu DiscoveryClientApp. W tym celu kliknij prawym przyciskiem myszy pliki w Eksplorator rozwiązań, wybierz polecenie Kopiuj, a następnie wybierz projekt DiscoveryClientApp, kliknij prawym przyciskiem myszy i wybierz polecenie Wklej.
Otwórz plik Program.cs.
Dodaj następujące
using
dyrektywy.using System.ServiceModel; using System.ServiceModel.Discovery; using Microsoft.ServiceModel.Samples;
Dodaj metodę statyczną o nazwie
FindCalculatorServiceAddress()
doProgram
klasy.static EndpointAddress FindCalculatorServiceAddress() { }
Ta metoda używa odnajdywania do wyszukiwania
CalculatorService
usługi.FindCalculatorServiceAddress
Wewnątrz metody utwórz nowe DiscoveryClient wystąpienie, przekazując UdpDiscoveryEndpoint element do konstruktora.static EndpointAddress FindCalculatorServiceAddress() { // Create DiscoveryClient DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint()); }
Informuje to WCF DiscoveryClient , że klasa powinna używać standardowego punktu końcowego odnajdywania UDP do wysyłania i odbierania komunikatów odnajdywania.
W następnym wierszu wywołaj metodę Find i określ FindCriteria wystąpienie zawierające kontrakt usługi, którego chcesz wyszukać. W tym przypadku określ wartość
ICalculator
.// Find ICalculatorService endpoints FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(ICalculator)));
Po wywołaniu metody Findsprawdź, czy istnieje co najmniej jedna zgodna usługa i zwróć EndpointAddress pierwszą zgodną usługę. W przeciwnym razie zwróć wartość
null
.if (findResponse.Endpoints.Count > 0) { return findResponse.Endpoints[0].Address; } else { return null; }
Dodaj metodę statyczną o nazwie
InvokeCalculatorService
doProgram
klasy.static void InvokeCalculatorService(EndpointAddress endpointAddress) { }
Ta metoda używa adresu punktu końcowego zwróconego z
FindCalculatorServiceAddress
, aby wywołać usługę kalkulatora.InvokeCalculatorService
Wewnątrz metody utwórz wystąpienieCalculatorServiceClient
klasy . Ta klasa jest definiowana przez przykład self-host . Został wygenerowany przy użyciu Svcutil.exe.// Create a client CalculatorClient client = new CalculatorClient();
W następnym wierszu ustaw adres punktu końcowego klienta na adres punktu końcowego zwrócony z
FindCalculatorServiceAddress()
adresu .// Connect to the discovered service endpoint client.Endpoint.Address = endpointAddress;
Bezpośrednio po kodzie poprzedniego kroku wywołaj metody uwidocznione przez usługę kalkulatora.
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();
Dodaj kod do
Main()
metody w klasie , aby wywołać metodęProgram
FindCalculatorServiceAddress
.public static void Main() { EndpointAddress endpointAddress = FindCalculatorServiceAddress(); }
W następnym wierszu wywołaj metodę
InvokeCalculatorService()
i przekaż adres punktu końcowego zwrócony zFindCalculatorServiceAddress()
adresu .if (endpointAddress != null) { InvokeCalculatorService(endpointAddress); } Console.WriteLine("Press <ENTER> to exit."); Console.ReadLine();
Aby przetestować aplikację
Otwórz wiersz polecenia z podwyższonym poziomem uprawnień i uruchom Service.exe.
Otwórz wiersz polecenia i uruchom Discoveryclientapp.exe.
Dane wyjściowe z service.exe powinny wyglądać podobnie do następujących danych wyjściowych.
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
Dane wyjściowe z Discoveryclientapp.exe powinny wyglądać podobnie do następujących danych wyjściowych.
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.
Przykład
Poniżej znajduje się lista kodu dla tego przykładu. Ponieważ ten kod jest oparty na przykładzie Self-Host , wyświetlane są tylko te pliki, które zostały zmienione.
// 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();
}
}
}