次の方法で共有


WCF 検出の概要

Discovery API は、WS-Discovery プロトコルを使用した Web サービスの動的な公開と検出のための統合プログラミング モデルを提供します。 これらの API を使用すると、サービスは自分自身とクライアントを発行して、発行されたサービスを見つけることができます。 サービスが検出可能になると、サービスはアナウンス メッセージを送信したり、検出要求をリッスンして応答したりできます。 探索可能なサービスは、Hello メッセージを送信してネットワークへの到着を通知し、Bye メッセージを送信してネットワークからの出発を通知できます。 サービスを検索するために、クライアントは、ネットワーク上のサービス コントラクトの種類、キーワード、スコープなどの特定の条件を含む Probe 要求を送信します。 サービスは Probe 要求を受け取り、それらが条件と一致するかどうかを判断します。 サービスが一致した場合は、サービスに連絡するために必要な情報を含む ProbeMatch メッセージをクライアントに送信して応答します。 クライアントは Resolve 要求を送信して、エンドポイント アドレスを変更した可能性のあるサービスを検索することもできます。 一致するサービスは、ResolveMatch メッセージをクライアントに送り返すことによって、Resolve要求に応答します。

アドホック モードとマネージド モード

Discovery API では、マネージド モードとアドホック モードの 2 つの異なるモードがサポートされています。 マネージド モードでは、使用可能なサービスに関する情報を保持する探索プロキシと呼ばれる一元化されたサーバーがあります。 探索プロキシには、さまざまな方法でサービスに関する情報を設定できます。 たとえば、サービスは起動時に探索プロキシにアナウンス メッセージを送信したり、プロキシがデータベースまたは構成ファイルからデータを読み取って、使用可能なサービスを決定したりできます。 探索プロキシの設定方法は、開発者が完全に決める必要があります。 クライアントは探索プロキシを使用して、使用可能なサービスに関する情報を取得します。 クライアントがサービスを検索すると、 Probe メッセージが探索プロキシに送信され、プロキシは、クライアントが検索しているサービスと一致することを認識しているサービスがあるかどうかを判断します。 一致する場合、検出プロキシはクライアントに ProbeMatch 応答を送信します。 クライアントは、プロキシから返されたサービス情報を使用して、サービスに直接接続できます。 マネージド モードの背後にある重要な原則は、探索要求がユニキャスト方式で 1 つの機関である探索プロキシに送信されるということです。 .NET Framework には、独自のプロキシを構築できる主要なコンポーネントが含まれています。 クライアントとサービスは、複数の方法でプロキシを見つけることができます。

  • プロキシはアドホック メッセージに応答できます。

  • プロキシは、起動時にアナウンス メッセージを送信できます。

  • クライアントとサービスは、特定の既知のエンドポイントを探すために記述できます。

アドホック モードでは、一元化されたサーバーはありません。 サービスアナウンスやクライアント要求などのすべての検出メッセージは、マルチキャスト方式で送信されます。 既定では、.NET Framework には UDP プロトコルを介したアドホック検出のサポートが含まれています。 たとえば、起動時に Hello アナウンスを送信するようにサービスが構成されている場合、UDP プロトコルを使用して既知のマルチキャスト アドレス経由で送信されます。 クライアントは、これらのお知らせを積極的にリッスンし、それに応じて処理する必要があります。 クライアントがサービスの Probe メッセージを送信すると、マルチキャスト プロトコルを使用してネットワーク経由で送信されます。 要求を受け取る各サービスは、Probe メッセージ内の条件と一致するかどうかを決定し、Probe メッセージで指定された条件とサービスが一致する場合は、ProbeMatch メッセージでクライアントに直接応答します。

WCF 検出を使用する利点

WCF Discovery は WS-Discovery プロトコルを使用して実装されるため、WS-Discovery を実装する他のクライアント、サービス、プロキシとも相互運用できます。 WCF Discovery は、既存の WCF API に基づいて構築されているため、探索機能を既存のサービスとクライアントに簡単に追加できます。 サービスの検出可能性は、アプリケーション構成設定を使用して簡単に追加できます。 さらに、WCF Discovery では、ピア ネット、名前付けオーバーレイ、HTTP などの他のトランスポートに対する探索プロトコルの使用もサポートされています。 WCF Discovery では、探索プロキシが使用されるマネージド モードの操作がサポートされます。 これにより、マルチキャスト メッセージをネットワーク全体に送信する代わりに、メッセージが検出プロキシに直接送信されるため、ネットワーク トラフィックを減らすことができます。 WCF Discovery を使用すると、Web サービスを使用する際の柔軟性も向上します。 たとえば、クライアントまたはサービスを再構成しなくても、サービスのアドレスを変更できます。 クライアントがサービスにアクセスする必要がある場合、Find要求を介してProbe メッセージを発行し、サービスが現在のアドレスで応答することを期待できます。 WCF Discovery を使用すると、クライアントは、コントラクトの種類、バインド要素、名前空間、スコープ、キーワード、またはバージョン番号など、さまざまな条件に基づいてサービスを検索できます。 WCF Discovery を使用すると、実行時とデザイン時の検出が可能になります。 アプリケーションに検出を追加すると、フォールト トレランスや自動構成などの他のシナリオを有効にすることができます。

サービスの公開

サービスを検出可能にするには、 ServiceDiscoveryBehavior をサービス ホストに追加し、探索エンドポイントを追加して探索メッセージをリッスンする場所を指定する必要があります。 次のコード例は、セルフホステッド サービスを変更して検出可能にする方法を示しています。

Uri baseAddress = new Uri($"http://{System.Net.Dns.GetHostName()}:8000/discovery/scenarios/calculatorservice/{Guid.NewGuid().ToString()}/");

// Create a ServiceHost for the CalculatorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress))
{
    // Add calculator endpoint
    serviceHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), string.Empty);

    // ** DISCOVERY ** //
    // Make the service discoverable by adding the discovery behavior
    serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());

    // ** DISCOVERY ** //
    // Add the discovery endpoint that specifies where to publish the services
    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("Press <ENTER> to terminate service.");
    Console.ReadLine();
}

ServiceDiscoveryBehavior インスタンスをサービスの説明に追加して、サービスを検出できるようにする必要があります。 検出要求をリッスンする場所をサービスに指示するには、 DiscoveryEndpoint インスタンスをサービス ホストに追加する必要があります。 この例では、サービスが UDP マルチキャスト トランスポート経由で検出要求をリッスンするように指定する UdpDiscoveryEndpoint ( DiscoveryEndpointから派生) が追加されます。 すべてのメッセージがマルチキャスト方式で送信されるため、 UdpDiscoveryEndpoint はアドホック検出に使用されます。

お知らせ

既定では、サービスパブリケーションはアナウンス メッセージを送信しません。 サービスは、アナウンス メッセージを送信するように構成する必要があります。 これにより、サービス ライターは探索メッセージをリッスンするのとは別にサービスを読み上げられるため、柔軟性が向上します。 サービスアナウンスは、探索プロキシまたはその他のサービス レジストリにサービスを登録するためのメカニズムとしても使用できます。 次のコードは、UDP バインディング経由でアナウンス メッセージを送信するようにサービスを構成する方法を示しています。

Uri baseAddress = new Uri($"http://{System.Net.Dns.GetHostName()}:8000/discovery/scenarios/calculatorservice/{Guid.NewGuid().ToString()}/");

// Create a ServiceHost for the CalculatorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress))
{
    // Add calculator endpoint
    serviceHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), string.Empty);

    // ** DISCOVERY ** //
    // Make the service discoverable by adding the discovery behavior
    ServiceDiscoveryBehavior discoveryBehavior = new ServiceDiscoveryBehavior();
    serviceHost.Description.Behaviors.Add(discoveryBehavior);

    // Send announcements on UDP multicast transport
    discoveryBehavior.AnnouncementEndpoints.Add(
      new UdpAnnouncementEndpoint());

    // ** DISCOVERY ** //
    // Add the discovery endpoint that specifies where to publish the services
    serviceHost.Description.Endpoints.Add(new UdpDiscoveryEndpoint());

    // Open the ServiceHost to create listeners and start listening for messages.
    serviceHost.Open();

    // The service can now be accessed.
    Console.WriteLine("Press <ENTER> to terminate service.");
    Console.ReadLine();
}

サービスの検出

クライアント アプリケーションは、 DiscoveryClient クラスを使用してサービスを検索できます。 開発者は、ProbeまたはResolveメッセージを送信する場所を指定する探索エンドポイントを渡すDiscoveryClient クラスのインスタンスを作成します。 その後、クライアントは、FindCriteria インスタンス内の検索条件を指定するFindを呼び出します。 一致するサービスが見つかった場合、 FindEndpointDiscoveryMetadataのコレクションを返します。 次のコードは、 Find メソッドを呼び出し、検出されたサービスに接続する方法を示しています。

class Client
{
    static EndpointAddress serviceAddress;
  
    static void Main()
    {  
        if (FindService())
        {
            InvokeService();
        }
    }  
  
    // ** DISCOVERY ** //  
    static bool FindService()  
    {  
        Console.WriteLine("\nFinding Calculator Service ..");  
        DiscoveryClient discoveryClient =
            new DiscoveryClient(new UdpDiscoveryEndpoint());  
  
        Collection<EndpointDiscoveryMetadata> calculatorServices =
            (Collection<EndpointDiscoveryMetadata>)discoveryClient.Find(new FindCriteria(typeof(ICalculator))).Endpoints;  
  
        discoveryClient.Close();  
  
        if (calculatorServices.Count == 0)  
        {  
            Console.WriteLine("\nNo services are found.");  
            return false;  
        }  
        else  
        {  
            serviceAddress = calculatorServices[0].Address;  
            return true;  
        }  
    }  
  
    static void InvokeService()  
    {  
        Console.WriteLine("\nInvoking Calculator Service at {0}\n", serviceAddress);  
  
        // Create a client  
        CalculatorClient client = new CalculatorClient();  
        client.Endpoint.Address = serviceAddress;  
        client.Add(10,3);  
    }
}  

検出とメッセージ レベルのセキュリティ

メッセージ レベルのセキュリティを使用する場合は、サービス検出エンドポイントで EndpointIdentity を指定し、クライアント検出エンドポイントで一致する EndpointIdentity を指定する必要があります。 メッセージ レベルのセキュリティの詳細については、「 メッセージ セキュリティ」を参照してください。

探索と Web ホステッド サービス

WCF サービスを検出できるようにするには、それらのサービスが実行されている必要があります。 IIS または WAS でホストされている WCF サービスは、IIS/WAS がサービスにバインドされたメッセージを受信するまで実行されないため、既定では検出できません。 Web-Hosted サービスを検出可能にする方法は 2 つあります。

  1. Windows Server AppFabric の自動開始機能を使用する

  2. 探索プロキシを使用してサービスに代わって通信する

Windows Server AppFabric には、メッセージを受信する前にサービスを開始できるようにする自動開始機能があります。 この自動開始セットを使用すると、IIS/WAS でホストされるサービスを検出可能に構成できます。 自動開始機能の詳細については、「 Windows Server AppFabric 自動開始機能」を参照してください。 自動開始機能を有効にするとともに、探索用にサービスを構成する必要があります。 詳細については、「 方法: プログラムによって WCF サービスに検出可能性を追加する」および「構成ファイルのクライアント構成検出」を参照してください。

探索プロキシは、サービスが実行されていないときに WCF サービスの代わりに通信するために使用できます。 プロキシは、プローブをリッスンしたり、メッセージを解決したり、クライアントに応答したりできます。 その後、クライアントはサービスに直接メッセージを送信できます。 クライアントがサービスにメッセージを送信すると、メッセージに応答するためにインスタンス化されます。 探索プロキシの実装の詳細については、「探索プロキシ の実装」を参照してください。

WCF 検出を正しく機能させるには、すべての NIC (ネットワーク インターフェイス コントローラー) に 1 つの IP アドレスのみが必要です。