DiscoveryClient と DynamicEndpoint は、サービスを検索するためにクライアント側で使用される 2 つのクラスです。 DiscoveryClient には、特定の条件セットに一致し、サービスに接続できるサービスの一覧が用意されています。 DynamicEndpoint は同じ操作を実行し、さらに、検出されたサービスのいずれかに自動的に接続します。 任意のエンドポイントを DynamicEndpointにすることができ、検索条件を構成に追加することもできます。そのため、 DynamicEndpoint はソリューションで検出が必要な場合に便利ですが、クライアント ロジックを変更したくない場合に便利です。エンドポイントを変更するだけで済みます。 DiscoveryClient 一方、検索操作を細かく制御するために使用できます。 それぞれの用途と利点については、以下で詳しく説明します。
DiscoveryClient
DiscoveryClientでは、同期および非同期の Find メソッド、FindCompletedイベント、およびFindProgressChanged イベントを定義します。 また、同期および非同期の Resolve メソッドと ResolveCompleted イベントも定義します。 サービスを検索するには、 Find または FindAsync メソッドを使用します。 どちらのメソッドも、コントラクト型の名前、スコープ、要求された結果の最大数、およびスコープの一致ルールを指定できる FindCriteria インスタンスを受け取ります。 FindCompletedイベントとFindProgressChanged イベントは、FindAsync メソッドを呼び出すときに使用できます。 FindProgressChanged がサービスからの応答を受け取るたびに、DiscoveryClient が発生します。 検索操作の進行状況を示す進行状況バーを表示するために使用できます。 また、受信した応答を検索する操作にも使用できます。 FindCompleted イベントは、検索操作が完了すると発生します。 これは、応答の最大数が受信されたか、 Duration が経過した場合に発生する可能性があります。 検索操作が完了すると、結果は FindResponse インスタンスで返されます。 FindResponseには、アドレス、コントラクト型名、拡張機能、リッスン URI、および一致するサービスのスコープを含むEndpointDiscoveryMetadataのコレクションが含まれています。 その後、この情報を使用して、一致するサービスのいずれかに接続して呼び出すことができます。 次の例は、System.ServiceModel.Discovery.DiscoveryClient.Find(System.ServiceModel.Discovery.FindCriteria) メソッドを呼び出し、返されたメタデータを使用して見つかったサービスを呼び出す方法を示しています。 Find(FindCriteria)を使用する利点は、見つかったエンドポイントの一覧をキャッシュし、後で使用できることです。 このキャッシュを使用すると、さまざまな障害状態を処理するカスタム ロジックを構築できます。
DiscoveryClient dc = new DiscoveryClient(new UdpDiscoveryEndpoint());
FindCriteria criteria = new FindCriteria(typeof(ICalculatorService));
FindResponse fr = dc.Find(criteria);
if (fr.Endpoints.Count > 0)
{
EndpointAddress ep = fr.Endpoints[0].Address;
CalculatorServiceClient client = new CalculatorServiceClient();
// 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);
}
else
Console.WriteLine("No matching endpoints found");
次の例は、検索操作を非同期的に実行する方法を示しています。
static void FindServiceAsync()
{
DiscoveryClient dc = new DiscoveryClient(new UdpDiscoveryEndpoint());
dc.FindCompleted += new EventHandler<FindCompletedEventArgs>( discoveryClient_FindCompleted);
dc.FindProgressChanged += new EventHandler<FindProgressChangedEventArgs>(discoveryClient_FindProgressChanged);
dc.FindAsync(new FindCriteria(typeof(ICalculatorService)));
}
static void discoveryClient_FindProgressChanged(object sender, FindProgressChangedEventArgs e)
{
Console.WriteLine("Found service at: " + e.EndpointDiscoveryMetadata.Address
}
static void discoveryClient_FindCompleted(object sender, FindCompletedEventArgs e)
{
if (e.Result.Endpoints.Count > 0)
{
EndpointAddress ep = e.Result.Endpoints[0].Address;
CalculatorServiceClient client = new CalculatorServiceClient();
// Connect to the discovered service endpoint
client.Endpoint.Address = ep;
Console.WriteLine("Invoking CalculatorService at {0}", ep);
double value1 = 100.00D;
double value2 = 15.99D;
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
}
else
Console.WriteLine("No matching endpoints found");
}
ResolveメソッドとResolveAsync(ResolveCriteria)メソッドを使用して、エンドポイント アドレスに基づいてサービスを検索します。 これは、エンドポイント アドレスがネットワーク アドレス指定できない場合に便利です。 Resolve メソッドは ResolveCriteria のインスタンスを受け取ります。これにより、解決するサービスのエンドポイント アドレス、解決操作の最大期間、および一連の拡張機能を指定できます。 次の例は、 Resolve メソッドを使用してサービスを解決する方法を示しています。
DiscoveryClient dc = new DiscoveryClient(new UdpDiscoveryEndpoint());
ResolveCriteria criteria = new ResolveCriteria(endpointAddress);
ResolveResponse response = dc.Resolve(criteria);
EndpointAddress newEp = response.EndpointDiscoveryMetadata.Address;
動的エンドポイント
DynamicEndpoint は、検出を実行し、一致するサービスを自動的に選択する標準エンドポイント (詳細については、 Standard エンドポイントを参照) です。 検索するコントラクトと使用するバインディングを渡す DynamicEndpoint を作成し、 DynamicEndpoint インスタンスを WCF クライアントに渡すだけです。 次の例は、 DynamicEndpoint を作成して使用して電卓サービスを呼び出す方法を示しています。 検出は、クライアントが開かれるたびに実行されます。 構成で定義されているすべてのエンドポイントは、エンドポイント構成要素にDynamicEndpoint属性を追加することで、kind ="dynamicEndpoint"
に変換することもできます。
DynamicEndpoint dynamicEndpoint = new DynamicEndpoint(ContractDescription.GetContract(typeof(ICalculatorService)), new WSHttpBinding());
CalculatorServiceClient client = new CalculatorServiceClient(dynamicEndpoint);
Console.WriteLine("Invoking CalculatorService");
Console.WriteLine();
double value1 = 100.00D;
double value2 = 15.99D;
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);