Condividi tramite


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

In questo argomento viene illustrato come rendere individuabile un servizio Windows Communication Foundation (WCF). È basato sull'esempio Servizio indipendente.

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

  1. Aprire la soluzione Self-Host in Visual Studio 2010. 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 il sistema ServiceModel.Discovery.dll o una delle relative dipendenze richiede una versione successiva di .NET Framework rispetto a quella specificata nel progetto. In questo caso fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni e scegliere Proprietà. Nella finestra Proprietà progetto verificare che Framework di destinazione sia impostato su .NET Framework versione 4.

  3. Aprire il file Service.cs e aggiungere l'istruzione using seguente.

    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 istruzioni using riportate di seguito.

    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 utilizzare 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 Servizio indipendente. È 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 eseguire il test dell'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

  1. L'output di Discoveryclientapp.exe deve essere analogo all'output indicato di seguito.

    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

Premere <INVIO> per uscire.

Esempio

Di seguito è riportato un elenco del codice per questo esempio. Poiché questo codice è basato sull'esempio Servizio indipendente, vengono elencati solo i file modificati. Per ulteriori informazioni su esempio Servizio indipendente, vedere Istruzioni per l'impostazione.

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

Vedere anche

Concetti

Panoramica di WCF Discovery
Modello a oggetti WCF Discovery