簡単なサンプルで使い方を紹介
今回は構成ファイルを一切使わずに、すべてコードで記述してみます。その方が、やっている事が分かりやすいと思うので。
サービスコントラクトとサービスクラスを用意
using System.ServiceModel; namespace DiscoverySample.Service { [ServiceContract] public interface IGreetingService { [OperationContract] string Greet(string name); } public class GreetingService : IGreetingService { public string Greet(string name) { return string.Format("Hello, {0}.", name); } } }
作成したサービスをホスト
WCF クライアントがサービスのエンドポイントを検出できるようにするには、ホスト側で設定が必要です。
using System; using System.ServiceModel; using System.ServiceModel.Discovery; using DiscoverySample.Service; namespace DiscoverySample.Host { class Program { static void Main(string[] args) { Uri baseAddress = new Uri("net.pipe://localhost/Test"); ServiceHost host = new ServiceHost(typeof(GreetingService), baseAddress); host.AddServiceEndpoint(typeof(IGreetingService), new NetNamedPipeBinding(), "Greet"); // クライアントがエンドポイントを検出できるようにする host.Description.Behaviors.Add(new ServiceDiscoveryBehavior()); host.AddServiceEndpoint(new UdpDiscoveryEndpoint()); host.Open(); Console.WriteLine("Enter で終了します。"); Console.ReadLine(); host.Close(); } } }
ServiceDiscoveryBehavior は、サービスのエンドポイントをクライアントが検出できるようにするビヘイビアです。ServiceDiscoveryBehavior は属性が用意されていないので、ServiceHost に直接突っ込んでいます。
UdpDiscoveryEndpoint は検出する際にクライアントから接続されるエンドポイントです。クライアントは、コネクションレスなプロトコルの UDP を使って、検出要求を一斉送信しているみたいです。
クライアントがエンドポイントを検出して接続
using System; using System.ServiceModel; using System.ServiceModel.Discovery; using DiscoverySample.Service; namespace DiscoverySample.Client { class Program { static void Main(string[] args) { // IGreetingService のエンドポイントを検出する FindCriteria criteria = new FindCriteria(typeof(IGreetingService)); DiscoveryClient client = new DiscoveryClient(new UdpDiscoveryEndpoint()); FindResponse response = client.Find(criteria); client.Close(); EndpointDiscoveryMetadata metaData = response.Endpoints[0]; // 検出したエンドポイントに接続する IGreetingService channel = ChannelFactory<IGreetingService>.CreateChannel( new NetNamedPipeBinding(), metaData.Address); string result = channel.Greet("Hayate"); ((IClientChannel)channel).Close(); Console.WriteLine(result); Console.WriteLine("Enter で終了します。"); Console.ReadLine(); } } }
エンドポイントの検出が終わるまでに 20 秒ほど待たされます。検出にかかる時間は FindCriteria.Duration プロパティで変更できますが、短くするとエンドポイントが見つからない可能性があるので、変更しないほうがよさそうです。