WCF ではコールバックが使えるので、試してみました。
コールバックを行うには、専用のインタフェースを定義する必要があります。
public interface IMyCallback { [OperationContract(IsOneWay = true)] void Reply(string message); }
次にサービスコントラクトを定義します。先日のコードをちょっと変更しただけの簡単なものです。ServiceContract 属性で、コールバック用インタフェースを指定しています。
[ServiceContract(CallbackContract = typeof(IMyCallback))] public interface IMyService { [OperationContract(IsOneWay = true)] void Call(string message); }
サービスを実装します。
public class MyService : IMyService { public void Call(string message) { Console.WriteLine(message); // コールバック用インタフェースを取得 IMyCallback client = OperationContext.Current.GetCallbackChannel<IMyCallback>(); // コールバック client.Reply("いっぱ〜つ!!"); } }
ホストを作成します。今回もコンソールアプリケーションで作成。構成ファイルを書くのが面倒なので、エンドポイントはコードで指定します。
class Program { static void Main(string[] args) { ServiceHost host = new ServiceHost(typeof(MyService.MyService)); host.AddServiceEndpoint( typeof(MyService.IMyService), // サービスコントラクト new NetTcpBinding(), // バインディングは TCP "net.tcp://localhost:8000/MyService"); host.Open(); Console.WriteLine("サービスを起動しました。"); Console.WriteLine("終了するには Enter キーを押してください。"); Console.ReadLine(); host.Close(); } }
コールバック用インタフェースを実装するクラスを作成。このクラスがコールバックを処理します。
public class MyCallback : IMyCallback { public void Reply(string message) { Console.WriteLine(message); } }
最後に、クライアントもコンソールアプリケーションで作成します。
static void Main(string[] args) { // コールバックで呼ばれるオブジェクト MyCallback callback = new MyCallback(); // 非同期双方向通信用のファクトリを生成 DuplexChannelFactory<IMyService> factory = new DuplexChannelFactory<IMyService>(callback); factory.Endpoint.Binding = new NetTcpBinding(); factory.Endpoint.Contract.ContractType = typeof(IMyService); factory.Endpoint.Address = new EndpointAddress("net.tcp://localhost:8000/MyService"); // チャネル生成 IMyService service = factory.CreateChannel(); // サービス呼び出し service.Call("ファイト〜!!"); // 接続を閉じる ((IChannel)service).Close(); Console.ReadLine(); }