2

WCFを使用してクライアントサーバー分散アプリケーションの作業を開始しました。クライアントもサーバーにリクエストを送信する必要があります。したがって、すべてのクライアントが同じイントラネット上にあるため、NetTcpBindingを使用して二重操作を実装することにしました。

サーバー側では、サーバーコントラクトを実装するサービスクラスにこれらの設定を使用します

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false)]

クライアントが初期化されるたびに、VisualStudioの'Add service reference'オプションを使用してサービスを追加することによって生成されたプロキシクラスのインスタンスを作成しています。プロキシが初期化された後Connect、サーバーにメッセージを送信します。

 _proxy.InnerChannel.Faulted += new EventHandler(InnerChannel_Faulted);
 _proxy.InnerChannel.Closing += new EventHandler(InnerChannel_Closing);
 //send a connect message to the server
 _proxy.ClientConnected(ClientHostName, Version, ClientID, ClientIP); 

これで、サーバーは接続されたクライアントへの参照を取得します。

OperationContext.Current.GetCallbackChannel<IClientEvents>()

これは非常に簡単で、派手なことは何もありません。ただし、サーバーがオンラインになった後、クライアントをサーバーに再接続させるのに少し問題があります。私のシナリオでは、最大50〜100のクライアントがサーバーに接続されており、サーバーと通信することはめったにありません。たとえば、平均して1時間に1つのリクエストがあります。

私が達成したいのは、オフライン中にクライアントを「ハング」させることです。このため、チャネルが状態になるたびにクライアント側で通信チャネルを再初期化しようとしますFaulted。これは問題なく機能します。しかし、サーバーを閉じようとすると、次のメッセージが表示されます

This could be because a client failed to close a sessionful channel within the required time.  

私は今、自分のシナリオに最も適切な実装を見つけるのに苦労しています。

  1. サービスコール後にチャネルを閉じない。このように、サーバーとの接続がダウンすると、クライアントは常にチャネルの再作成を試みます(たとえば、1分の間隔)。ただし、チャンネルを常に開いたままにしておくのはあまり意味がないので、このアプローチについてはよくわかりません。
  2. 各呼び出しの後にチャネルを閉じ、サーバーに新しい呼び出しを行うときに再作成します。これはサービス呼び出しを行うときに正常に機能しますが、サーバーがクライアントに通知を送信したい場合はどうなりますか?サーバー側のコールバック参照は無効になります。クライアントが新しい接続メッセージを送信して新しいコールバック参照を取得するのを待つ必要がありますよね?この場合、サーバーが常にクライアントに接続できるようにするために、サーバーに対してPing()と同様の別の呼び出しを定期的に行う必要がありますか?

私はまだWCFデュプレックス操作に関する資料を読んでいますが、後で問題が発生しないように、どちらのアプローチが優れているかを判断できません。

アドバイスありがとうございます!

4

0 に答える 0