WCF

双方向通信によるサーバープッシュ

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);
}

サービスの実装

ポイントはアクセスしてきたクライアントのコールバックをサーバー上で一括的に管理することです。ニーズによって、管理されているコールバックへ送信します。

※注意点
InstanceContextMode = InstanceContextMode.Single に設定したら、サーバー側の通信インスタンスが一つになり、クライアントのコールバックを管理するオブジェクトは、いつも最後に登録した端末となります。

[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%吸着

コメント:



(画像の文字列を入力して下さい)

トップ   編集 凍結 差分 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019/12/02 (月) 12:44:11 (1627d)

PCpዾyǗlgĂ܂}WŔ܂z 萔O~ył񂫁z Yahoo yV NTT-X Store

z[y[W ̃NWbgJ[h COiq ӂ邳Ɣ[ COsیI COze