Condividi tramite


Procedura: aggiungere capacità di individuazione a un client e un servizio WCF a livello di codice

Questo argomento illustra come rendere individuabile un servizio Windows Communication Foundation (WCF). Si basa sull'esempio di self-host.

Per configurare l'esempio di servizio indipendente esistente per l'individuazione

  1. Aprire la soluzione Self-Host in Visual Studio 2012. L'esempio si trova nella directory TechnologySamples\Basic\Service\Hosting\SelfHost.

  2. Aggiungere al progetto di servizio un riferimento a System.ServiceModel.Discovery.dll. Potrebbe essere visualizzato un messaggio di errore a indicare che "System. ServiceModel.Discovery.dll o una delle relative dipendenze richiede una versione successiva di .NET Framework rispetto a quella specificata nel progetto…" Se viene visualizzato questo messaggio, fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni e scegliere Proprietà. Nella finestra Proprietà progetto verificare che il framework di destinazione sia .NET Framework 4.6.1.

  3. Aprire il file Service.cs e aggiungere la direttiva seguente using .

    using System.ServiceModel.Discovery;
    
  4. Nel metodo Main(), all'interno dell'istruzione using, aggiungere un'istanza ServiceDiscoveryBehavior all'host del servizio.

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

    ServiceDiscoveryBehavior specifica che il servizio a cui è applicato è individuabile.

  5. Aggiungere UdpDiscoveryEndpoint all'host del servizio subito dopo il codice che aggiunge ServiceDiscoveryBehavior.

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

    Questo codice specifica che i messaggi di individuazione devono essere inviati all'endpoint di individuazione UDP standard.

Per creare un'applicazione client che utilizza l'individuazione per chiamare il servizio

  1. Aggiungere alla soluzione una nuova applicazione console denominata DiscoveryClientApp.

  2. Aggiungere un riferimento a System.ServiceModel.dll e System.ServiceModel.Discovery.dll

  3. Copiare i file GeneratedClient.cs e App.config dal progetto client esistente al nuovo progetto DiscoveryClientApp. A tale scopo fare clic con il pulsante destro del mouse sui file in Esplora soluzioni, scegliere Copia, quindi fare clic sul progetto DiscoveryClientApp, fare clic con il pulsante destro del mouse e scegliere Incolla.

  4. Aprire Program.cs.

  5. Aggiungere le direttive seguenti using .

    using System.ServiceModel;
    using System.ServiceModel.Discovery;
    using Microsoft.ServiceModel.Samples;
    
  6. Aggiungere un metodo statico denominato FindCalculatorServiceAddress() alla classe Program.

    static EndpointAddress FindCalculatorServiceAddress()
    {
    }
    

    Questo metodo utilizza l'individuazione per cercare il servizio CalculatorService.

  7. Creare nel metodo FindCalculatorServiceAddress una nuova istanza DiscoveryClient, passando un elemento UdpDiscoveryEndpoint al costruttore.

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

    In questo modo WCF viene informato del fatto che la classe DiscoveryClient deve usare l'endpoint di individuazione UDP standard per inviare e ricevere messaggi di individuazione.

  8. Alla riga successiva, chiamare il metodo Find e specificare un'istanza FindCriteria che contiene il contratto di servizio che si desiderare cercare. In questo caso specificare ICalculator.

    // Find ICalculatorService endpoints
    FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(ICalculator)));
    
  9. Successivamente alla chiamata a Find, verificare se sia disponibile almeno un servizio corrispondente e restituire l'elemento EndpointAddress del primo servizio corrispondente. In caso contrario, restituire null.

    if (findResponse.Endpoints.Count > 0)
    {
        return findResponse.Endpoints[0].Address;
    }
    else
    {
        return null;
    }
    
  10. Aggiungere un metodo statico denominato InvokeCalculatorService alla classe Program.

    static void InvokeCalculatorService(EndpointAddress endpointAddress)
    {
    }
    

    Questo metodo utilizza l'indirizzo endpoint restituito da FindCalculatorServiceAddress per chiamare il servizio di calcolo.

  11. Creare all'interno del metodo InvokeCalculatorService un'istanza della classe CalculatorServiceClient. Questa classe viene definita dall'esempio Self-Host. È stata generata utilizzando Svcutil.exe.

    // Create a client
    CalculatorClient client = new CalculatorClient();
    
  12. Alla riga successiva impostare l'indirizzo endpoint del client sull'indirizzo endpoint restituito da FindCalculatorServiceAddress().

    // Connect to the discovered service endpoint
    client.Endpoint.Address = endpointAddress;
    
  13. Immediatamente dopo il codice per il passaggio precedente, chiamare i metodi esposti dal servizio di calcolo.

    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. Aggiungere codice al metodo Main() nella classe Program per chiamare FindCalculatorServiceAddress.

    public static void Main()
    {
        EndpointAddress endpointAddress = FindCalculatorServiceAddress();
    }
    
  15. Alla riga successiva chiamare InvokeCalculatorService() e passare l'indirizzo endpoint restituito da FindCalculatorServiceAddress().

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

Per testare l'applicazione

  1. Aprire un prompt dei comandi con privilegi elevati ed eseguire Service.exe.

  2. Aprire un prompt dei comandi ed eseguire Discoveryclientapp.exe.

  3. L'output di service.exe deve essere analogo all'output indicato di seguito.

    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
    
  4. L'output di Discoveryclientapp.exe deve essere analogo all'output indicato di seguito.

    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.
    

Esempio

Di seguito è riportato un elenco del codice per questo esempio. Poiché questo codice è basato sull'esempio Self-Host, vengono elencati solo i file modificati.

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

        }
    }
}

Vedi anche