Vorgehensweise: Programmgesteuertes Hinzufügen der Ermittelbarkeit zu einem WCF-Dienst und -Client

In diesem Thema wird erläutert, wie Sie erreichen, dass ein Windows Communication Foundation (WCF)-Dienst erkennbar ist und danach gesucht werden kann. Grundlage hierfür ist das Beispiel unter Selbst gehostete Dienste (möglicherweise in englischer Sprache).

So konfigurieren Sie das vorhandene Beispiel unter "Selbst gehostete Dienste" für die Suche

  1. Öffnen Sie in Visual Studio 2010 die entsprechende Projektmappe (Self-Host). Das Beispiel befindet sich im Verzeichnis "TechnologySamples\Basic\Service\Hosting\SelfHost".

  2. Fügen Sie dem Dienstprojekt einen Verweis auf System.ServiceModel.Discovery.dll hinzu. Ggf. wird folgende Fehlermeldung angezeigt: "System. ServiceModel.Discovery.dll oder eine der Abhängigkeiten erfordert eine spätere Version von .NET Framework als im Projekt angegeben…". Falls diese Nachricht angezeigt wird, klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie Eigenschaften. Stellen Sie im Fenster Projekteigenschaften sicher, dass .NET Framework, Version 4 als Zielframework angegeben ist.

  3. Öffnen Sie die Datei "Service.cs", und fügen Sie die folgende using-Anweisung hinzu.

    using System.ServiceModel.Discovery;
    
  4. Fügen Sie in der Main()-Methode innerhalb der using-Anweisung dem Diensthost eine ServiceDiscoveryBehavior-Instanz hinzu.

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

    Das ServiceDiscoveryBehavior-Objekt gibt an, dass der Dienst, auf den dieses Verhalten angewendet wird, erkennbar ist.

  5. Fügen Sie dem Diensthost direkt nach dem Code, in dem ServiceDiscoveryBehavior hinzugefügt wird, ein UdpDiscoveryEndpoint-Objekt hinzu.

    // Add ServiceDiscoveryBehavior
    serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
    
    // Add a UdpDiscoveryEndpoint
    serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
    

    Dieser Code gibt an, dass Suchmeldungen an den standardmäßigen UDP-Suchendpunkt gesendet werden sollen.

So erstellen Sie eine Clientanwendung, die die Suche zum Aufrufen des Diensts verwendet

  1. Fügen Sie der Projektmappe eine neue Konsolenanwendung mit dem Namen DiscoveryClientApp hinzu.

  2. Fügen Sie einen Verweis auf System.ServiceModel.dll und System.ServiceModel.Discovery.dll hinzu.

  3. Kopieren Sie die Dateien "GeneratedClient.cs" und "App.config" aus dem vorhandenen Clientprojekt in das neue DiscoveryClientApp-Projekt. Klicken Sie hierzu im Projektmappen-Explorer mit der rechten Maustaste auf die Dateien, wählen Sie Kopieren aus, und wählen Sie dann das Projekt DiscoveryClientApp aus. Klicken Sie mit der rechten Maustaste, und wählen Sie Einfügen aus.

  4. Öffnen Sie die Datei "Program.cs".

  5. Fügen Sie die folgenden using-Anweisungen hinzu.

    using System.ServiceModel;
    using System.ServiceModel.Discovery;
    using Microsoft.ServiceModel.Samples;
    
  6. Fügen Sie der Program-Klasse eine statische Methode mit dem Namen FindCalculatorServiceAddress() hinzu.

    static EndpointAddress FindCalculatorServiceAddress()
    {
    }
    

    Diese Methode verwendet die Suche (Discovery) zum Suchen nach dem CalculatorService-Dienst.

  7. Erstellen Sie in der FindCalculatorServiceAddress-Methode eine neue DiscoveryClient-Instanz, die einen UdpDiscoveryEndpoint an den Konstruktor übergibt.

    static EndpointAddress FindCalculatorServiceAddress()
    {
        // Create DiscoveryClient
        DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
    }
    

    Auf diese Weise wird WCF mitgeteilt, dass die DiscoveryClient-Klasse den standardmäßigen UDP-Suchendpunkt zum Senden und Empfangen von Suchmeldungen verwenden soll.

  8. Rufen Sie in der nächsten Zeile die Find-Methode auf, und geben Sie eine FindCriteria-Instanz an, die den zu suchenden Dienstvertrag enthält. Geben Sie in diesem Fall ICalculator an.

    // Find ICalculatorService endpoints            
    FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(ICalculator)));
    
  9. Überprüfen Sie nach dem Aufruf von Find, ob mindestens ein übereinstimmender Dienst vorhanden ist, und geben Sie für den ersten übereinstimmenden Dienst EndpointAddress zurück. Geben Sie andernfalls NULL zurück.

    if (findResponse.Endpoints.Count > 0)
    {
        return findResponse.Endpoints[0].Address;
    }
    else
    {
        return null;
    }
    
  10. Fügen Sie der Program-Klasse eine statische Methode mit dem Namen InvokeCalculatorService hinzu.

    static void InvokeCalculatorService(EndpointAddress endpointAddress)
    {
    }
    

    Diese Methode verwendet die von FindCalculatorServiceAddress zurückgegebene Endpunktadresse zum Aufrufen des Rechnerdiensts.

  11. Erstellen Sie innerhalb der InvokeCalculatorService-Methode eine Instanz der CalculatorServiceClient-Klasse. Diese Klasse wird über das Beispiel Selbst gehostete Dienste definiert. Sie wurde mithilfe von "Svcutil.exe" generiert.

    // Create a client
    CalculatorClient client = new CalculatorClient();
    
  12. Legen Sie in der nächsten Zeile die Endpunktadresse des Clients auf die Endpunktadresse fest, die von FindCalculatorServiceAddress() zurückgegeben wurde.

    // Connect to the discovered service endpoint
    client.Endpoint.Address = endpointAddress;
    
  13. Rufen Sie direkt nach dem Code für den vorherigen Schritt die vom Rechnerdienst verfügbar gemachten Methoden auf.

    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. Fügen Sie der Main()-Methode in der Program-Klasse Code zum Aufrufen von FindCalculatorServiceAddress hinzu.

    public static void Main()
    {
        EndpointAddress endpointAddress = FindCalculatorServiceAddress();
    }
    
  15. Rufen Sie in der nächsten Zeile InvokeCalculatorService() auf, und übergeben Sie die Endpunktadresse, die von FindCalculatorServiceAddress() zurückgegeben wurde.

    if (endpointAddress != null)
    {
        InvokeCalculatorService(endpointAddress);
    }
    
    Console.WriteLine("Press <ENTER> to exit.");
    Console.ReadLine();
    

So testen Sie die Anwendung

  1. Öffnen Sie eine Eingabeaufforderung mit erhöhten Rechte, und führen Sie "Service.exe" aus.

  2. Öffnen Sie eine Eingabeaufforderung, und führen Sie "Discoveryclientapp.exe" aus.

  3. Die Ausgabe der Datei "service.exe" sollte der folgenden Ausgabe ähneln.

    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

  1. Die Ausgabe der Datei "Discoveryclientapp.exe" sollte der folgenden Ausgabe ähneln.

    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.

Beispiel

Es folgt eine Auflistung des Codes für dieses Beispiel. Da dieser Code auf dem Beispiel unter Selbst gehostete Dienste basiert, sind nur die geänderten Dateien aufgeführt. Weitere Informationen über zum Beispiel unter "Selbst gehostete Dienste" finden Sie unter Setupanweisungen (möglicherweise in englischer Sprache).

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

Siehe auch

Konzepte

Übersicht über die WCF-Suche
Objektmodell der WCF-Suche