双方向通信によるサーバープッシュ WCF の双方向通信をサポートするバインディングを利用して、サーバープッシュの機能を実現できます。ServiceContractAttribute.CallbackContract のプロパティにより、クライアント アプリケーションは、サービス側がクライアントへの送受信操作をリッスンできます。 コールバックインターフェイスの定義 †public interface IDuplexCallback { [OperationContract(IsOneWay = true)] void SendData(string eqn); } サービスインターフェイスの定義 †コールバックの呼び出しがある OperationContract は、IsOneWay を true に設定する必要があります。 [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IDuplexCallback))] public interface IMyService { [OperationContract(IsOneWay = true)] void Join(string name); [OperationContract(IsOneWay = true)] void Say(string message); } サービスの実装 †ポイントはアクセスしてきたクライアントのコールバックをサーバー上で一括的に管理することです。ニーズによって、管理されているコールバックへ送信します。 ※注意点 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)] public class MyService : IMyService { private static Object syncObj = new Object(); public delegate void JoinedEventHandler(string sender); //各クライアントのコールバックを管理する static Dictionary<string, JoinedEventHandler> endPointManager = new Dictionary<string, JoinedEventHandler>(); IDuplexCallback callback = null; public void Join(string name) { lock (syncObj) { if (!endPointManager.Keys.Contains(name)) { endPointManager.Add(name, (x) => { callback.SendData(x); }); } } if (endPointManager.Keys.Count > 0) { callback = OperationContext.Current.GetCallbackChannel<IDuplexCallback>(); BroadcastMessage(name); } } public void Say(string message) { if (endPointManager.Keys.Count > 0) { BroadcastMessage(message); } } private void BroadcastMessage(string str) { foreach (string key in endPointManager.Keys) { endPointManager[key].Invoke(string.Format("key:{0} Vaule={1}", key, str)); } } } サービスの設定 †説明する必要がありません、ごく一般的な NetTcpBinding の設定です。 <services> <service name="Samples1.MyService"> <endpoint address="" binding="netTcpBinding" contract="Samples1.IMyService" bindingConfiguration="tcpbinding"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:4506/Service1" /> </baseAddresses> </host> </service> </services> クライアントの呼び出す †public partial class Form1 : Form, WindowsFormsApplication1.ServiceReference1.IMyServiceCallback { InstanceContext context_; MyServiceClient client_; public Form1() { InitializeComponent(); context_ = new InstanceContext(this); client_ = new MyServiceClient(context_); } private void button1_Click(object sender, EventArgs e) { client_.Join(this.textBoxInput.Text); } public void SendData(string eqn) { this.textBox1.Text += "SendData>"+ eqn + Environment.NewLine; } } セシウム137を97.7%吸着 コメント: |