次の方法で共有


プログラムを使用して探索可能性に WCF サービスとクライアントを追加する方法

このトピックでは、Windows Communication Foundation (WCF) サービスを探索可能にする方法について説明します。これは、自己ホストのサンプルに基づいています。

既存の自己ホスト サービス サンプルを探索用に構成するには

  1. Visual Studio 2010 で自己ホスト ソリューションを開きます。このサンプルは、TechnologySamples\Basic\Service\Hosting\SelfHost ディレクトリにあります。

  2. System.ServiceModel.Discovery.dll への参照をサービス プロジェクトに追加します。"System.ServiceModel.Discovery.dll またはその依存ファイルに、プロジェクトに指定されているバージョンよりも新しいバージョンの .NET Framework が必要です" というエラーメッセージが表示されることがあります。このメッセージが表示された場合は、ソリューション エクスプローラーでプロジェクトを右クリックし、[プロパティ] をクリックします。[プロジェクトのプロパティ] ウィンドウで、[ターゲット フレームワーク] が .NET Framework Version 4 になっていることを確認します。

  3. Service.cs ファイルを開き、次の using ステートメントを追加します。

    using System.ServiceModel.Discovery;
    
  4. Main() メソッドの using ステート内で、ServiceDiscoveryBehavior インスタンスをサービス ホストに追加します。

    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 は、それが適用されているサービスが探索可能であることを指定します。

  5. UdpDiscoveryEndpoint を、ServiceDiscoveryBehavior を追加するコードの直後でサービス ホストに追加します。

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

    このコードは、探索メッセージを標準の UDP 探索エンドポイントに送信する必要があることを指定します。

探索を使用してサービスを呼び出すクライアント アプリケーションを作成するには

  1. 新しいコンソール アプリケーションを DiscoveryClientApp というソリューションに追加します。

  2. System.ServiceModel.dll および System.ServiceModel.Discovery.dll への参照を追加します。

  3. GeneratedClient.cs ファイルおよび App.config ファイルを、既存のクライアント プロジェクトから新しい DiscoveryClientApp プロジェクトに追加します。これを行うには、ソリューション エクスプローラーでこれらのファイルを右クリックして [コピー] を選択し、[DiscoveryClientApp] プロジェクトを右クリックして [貼り付け] を選択します。

  4. Program.cs を開きます。

  5. 次の using ステートメントを追加します。

    using System.ServiceModel;
    using System.ServiceModel.Discovery;
    using Microsoft.ServiceModel.Samples;
    
  6. FindCalculatorServiceAddress() という静的メソッドを Program クラスに追加します。

    static EndpointAddress FindCalculatorServiceAddress()
    {
    }
    

    このメソッドは、探索を使用して CalculatorService サービスを検索します。

  7. FindCalculatorServiceAddress メソッド内で、新しい DiscoveryClient インスタンスを作成し、UdpDiscoveryEndpoint をコンストラクターに渡します。

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

    これにより、WCF は、DiscoveryClient クラスが標準の UDP 探索エンドポイントを使用して探索メッセージを送受信する必要があることを認識します。

  8. 次の行では、Find メソッドを呼び出し、検索対象のサービス コントラクトを含む FindCriteria インスタンスを指定します。ここでは、ICalculator を指定します。

    // Find ICalculatorService endpoints            
    FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(ICalculator)));
    
  9. Find への呼び出しの後で、一致するサービスが少なくとも 1 つあるかどうかを確認し、最初に一致したサービスの EndpointAddress を返します。一致するサービスがない場合は null を返します。

    if (findResponse.Endpoints.Count > 0)
    {
        return findResponse.Endpoints[0].Address;
    }
    else
    {
        return null;
    }
    
  10. InvokeCalculatorService という名前の静的メソッドを Program クラスに追加します。

    static void InvokeCalculatorService(EndpointAddress endpointAddress)
    {
    }
    

    このメソッドは、FindCalculatorServiceAddress から返されたエンドポイント アドレスを使用して、電卓サービスを呼び出します。

  11. InvokeCalculatorService メソッド内で、CalculatorServiceClient クラスのインスタンスを作成します。このクラスは、自己ホストのサンプルで定義されます。これは、Svcutil.exe を使用して生成されました。

    // Create a client
    CalculatorClient client = new CalculatorClient();
    
  12. 次の行では、クライアントのエンドポイント アドレスを、FindCalculatorServiceAddress() から返されたエンドポイント アドレスに設定します。

    // Connect to the discovered service endpoint
    client.Endpoint.Address = endpointAddress;
    
  13. 前の手順のコードの直後に、電卓サービスで公開されたメソッドを呼び出します。

    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. Program クラスの Main() メソッドにコードを追加して、FindCalculatorServiceAddress を呼び出します。

    public static void Main()
    {
        EndpointAddress endpointAddress = FindCalculatorServiceAddress();
    }
    
  15. 次の行では、InvokeCalculatorService() を呼び出し、FindCalculatorServiceAddress() から返されたエンドポイント アドレスを渡します。

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

アプリケーションをテストするには

  1. 権限のレベルが高いコマンド プロンプトを開き、Service.exe を実行します。

  2. コマンド プロンプトを開き、Discoveryclientapp.exe を実行します。

  3. Service.exe からの出力は次のようになります。

    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. Discoveryclientapp.exe からの出力は次のようになります。
    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 &lt;ENTER&gt; to exit.

このサンプルで使用されているコード全体の一覧を次に示します。このコードは、自己ホストのサンプルに基づいているため、変更されたファイルだけが示されています。自己ホスト サンプル詳細情報、「セットアップ手順」を参照してください。

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

参照

概念

WCF Discovery の概要
WCF Discovery オブジェクト モデル