Postupy: Programové přidání možností rozpoznání do klienta a služby WCF
Toto téma vysvětluje, jak nastavit, aby služba WCF (Windows Communication Foundation) byla zjistitelná. Je založená na ukázce samoobslužného hostitele .
Konfigurace existující ukázky samoobslužné služby pro zjišťování
Otevřete řešení samoobslužného hostitele v sadě Visual Studio 2012. Ukázka se nachází v adresáři TechnologySamples\Basic\Service\Hosting\SelfHost.
Přidejte odkaz na
System.ServiceModel.Discovery.dll
projekt služby. Může se zobrazit chybová zpráva "Systém". ServiceModel.Discovery.dll nebo některé z jejích závislostí vyžaduje novější verzi rozhraní .NET Framework, než je verze zadaná v projektu ..." Pokud se tato zpráva zobrazí, klikněte pravým tlačítkem myši na projekt v Průzkumník řešení a zvolte Vlastnosti. V okně Vlastnosti projektu se ujistěte, že cílová architektura je .NET Framework 4.6.1.Otevřete soubor Service.cs a přidejte následující
using
direktivu.using System.ServiceModel.Discovery;
Main()
V metodě v příkazuusing
přidejte ServiceDiscoveryBehavior instanci do hostitele služby.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()); // ... } }
Určuje ServiceDiscoveryBehavior , že služba, na kterou se vztahuje, je zjistitelná.
UdpDiscoveryEndpoint Přidejte do hostitele služby hned za kód, který přidá ServiceDiscoveryBehavior.
// Add ServiceDiscoveryBehavior serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior()); // Add a UdpDiscoveryEndpoint serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
Tento kód určuje, že zprávy zjišťování by se měly odesílat do standardního koncového bodu zjišťování UDP.
Vytvoření klientské aplikace, která ke volání služby používá zjišťování
Přidejte do řešení novou konzolovou aplikaci s názvem
DiscoveryClientApp
.Přidání odkazu na
System.ServiceModel.dll
System.ServiceModel.Discovery.dll
Zkopírujte soubory GeneratedClient.cs a App.config z existujícího klientského projektu do nového projektu DiscoveryClientApp. Uděláte to tak, že kliknete pravým tlačítkem na soubory v Průzkumník řešení, vyberete Kopírovat a pak vyberete projekt DiscoveryClientApp, kliknete pravým tlačítkem myši a vyberete Vložit.
Otevřete soubor Program.cs.
Přidejte následující
using
direktivy.using System.ServiceModel; using System.ServiceModel.Discovery; using Microsoft.ServiceModel.Samples;
Přidejte statickou metodu
Program
volanouFindCalculatorServiceAddress()
do třídy.static EndpointAddress FindCalculatorServiceAddress() { }
Tato metoda používá zjišťování k vyhledání
CalculatorService
služby.FindCalculatorServiceAddress
Uvnitř metody vytvořte novou DiscoveryClient instanci, která předává UdpDiscoveryEndpoint konstruktoru.static EndpointAddress FindCalculatorServiceAddress() { // Create DiscoveryClient DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint()); }
To wcf říká, že DiscoveryClient třída by měla používat standardní koncový bod zjišťování UDP k odesílání a přijímání zpráv zjišťování.
Na dalším řádku zavolejte metodu Find a zadejte FindCriteria instanci, která obsahuje kontrakt služby, který chcete vyhledat. V tomto případě zadejte
ICalculator
.// Find ICalculatorService endpoints FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(ICalculator)));
Po volání Findzkontrolujte, jestli existuje aspoň jedna odpovídající služba, a vraťte EndpointAddress první odpovídající službu. V opačném případě vrátit
null
.if (findResponse.Endpoints.Count > 0) { return findResponse.Endpoints[0].Address; } else { return null; }
Přidejte statickou metodu pojmenovanou
InvokeCalculatorService
doProgram
třídy.static void InvokeCalculatorService(EndpointAddress endpointAddress) { }
Tato metoda používá adresu koncového bodu vrácenou z
FindCalculatorServiceAddress
volání služby kalkulačky.InvokeCalculatorService
Uvnitř metody vytvořte instanciCalculatorServiceClient
třídy. Tato třída je definována ukázkou self-Host . Vygeneroval se pomocí Svcutil.exe.// Create a client CalculatorClient client = new CalculatorClient();
Na dalším řádku nastavte adresu koncového bodu klienta na adresu koncového bodu vrácenou z
FindCalculatorServiceAddress()
.// Connect to the discovered service endpoint client.Endpoint.Address = endpointAddress;
Ihned po kódu předchozího kroku volejte metody vystavené službou kalkulačky.
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();
Přidejte kód do
Main()
metody veProgram
třídě pro voláníFindCalculatorServiceAddress
.public static void Main() { EndpointAddress endpointAddress = FindCalculatorServiceAddress(); }
Na dalším řádku zavolejte
InvokeCalculatorService()
adresu koncového bodu vrácenou z adresy koncového bodu a předejte ji.FindCalculatorServiceAddress()
if (endpointAddress != null) { InvokeCalculatorService(endpointAddress); } Console.WriteLine("Press <ENTER> to exit."); Console.ReadLine();
Testování aplikace
Otevřete příkazový řádek se zvýšenými oprávněními a spusťte Service.exe.
Otevřete příkazový řádek a spusťte Discoveryclientapp.exe.
Výstup z service.exe by měl vypadat jako následující výstup.
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
Výstup z Discoveryclientapp.exe by měl vypadat jako následující výstup.
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.
Příklad
Následuje seznam kódu pro tuto ukázku. Vzhledem k tomu, že tento kód je založený na ukázce samoobslužného hostitele , jsou uvedeny pouze soubory, které se změnily.
// 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();
}
}
}