33

ファイアウォールを介したクライアントへの WCF プッシュ」も参照してください。

WCFサーバーに接続するWCFクライアントが必要です。サーバー上のデータが変更された場合、クライアントはその表示を更新する必要があります。

クライアントとサーバーの間にファイアウォールがある可能性が高いためです。

  • すべての通信は HTTP 経由である必要があります
  • サーバーは、クライアントに対して (物理的な) 発信呼び出しを行うことができません。

私はクライアントとサーバーの両方を書いているので、soap などの使用のみにソリューションを制限する必要はありません。


「ロングポーリング」/「コメット」などの組み込みサポートを探しています


WCF でロング ポーリングを実装する方法について Drew Marsh からの最も有益な回答をありがとう。しかし、WCF の主な「セールス ポイント」は、構成ファイルで使用するチャネルを構成するだけで、この種のことができることだと思いました。 たとえば、論理的には双方向で、物理的には着信のみのチャネルが必要です。

4

5 に答える 5

49

あなたはすでに答えを知っているように思えます:ロングポーリングを使用してください。:) したがって、説明しなければならない唯一のことは、WCF を使用して可能な限り最も効率的な方法でこれを達成する方法です。


基礎:

  1. 最初に、各「長いポーリング」の長さを決定します。議論のために、5 分のタイムアウトを選択します。
  2. クライアント側バインディングで、sendTimeout="00:05:00".
  3. ロング ポーリングに XmlHttpRequest (XHR) を使用するのと同様に、実際にタイムアウトが発生した場合は、それを検出して次のポーリング リクエストを再発行する必要があります。これは、WCF では非常に簡単です。なぜなら、特定の例外 があるためTimeoutExceptionです。これをキャッチして、これが問題であり、他の例外であったことを簡単に検出できます。
  4. WCF サービスをホストしている方法によっては、最大 5 分間の処理を許可するように構成する必要があります。純粋な WCF の観点からは、必ずreceiveTimeout="00:05:00". ただし、ASP.NET 内でホストしている場合は、ASP.NET ランタイムのタイムアウトを長く設定する必要があります<httpRuntime executionTimeout="300" />(注:この属性の測定値は秒単位です)。

クライアントで効率的であること

サービスを同期的に呼び出すようにクライアントをセットアップし、クライアントが応答を待っている間に 5​​ 分間ブロックする場合、それはシステム リソースの効率的な使用とは言えません。これらの呼び出しをバックグラウンド スレッドに配置することもできますが、呼び出しが未処理である間、スレッド リソースを食いつぶすことになります。これに対処する最も効率的な方法は、非同期操作を使用することです。

サービス コントラクトを手動で作成している場合は、MSDN のこのセクションでOperationContractAttribute.AsyncPatternBeginXXX、各呼び出しに/ EndXXXasync メソッド ペアを追加する方法の詳細を確認することをお勧めします。ただし、svcutil操作コントラクトを生成するために を使用している場合、非同期メソッドを生成するために必要なことは/async、コマンド ラインでオプションを渡すことだけです。このトピックの詳細については、MSDN の同期と非同期のトピックを参照してください

非同期操作の定義が完了したので、パターンは XHR での作業に非常によく似ています。デリゲートBeginXXXを渡すメソッドを呼び出しAsyncCallbackます。このBeginXXXメソッドは を返しますIAsyncResult。これは、操作を待機できるようにしたい場合 (より高度なシナリオでは) 保持するか、無視することができます。その後、WCF インフラストラクチャは要求を非同期的にサーバーに送信し、裏での反応。応答が受信されるか、例外が発生すると、BeginXXXメソッドに渡したコールバックが呼び出されます。EndXXXこのコールバック メソッド内で、渡された を渡す対応するメソッドを呼び出す必要がありIAsyncResultます。への通話中にEndXXXメソッドの呼び出し中に発生した可能性のあるあらゆる種類の論理エラーに対処するために例外処理を採用する必要がありますが、これは、TimeoutException先ほど説明したエラーをキャッチできる場所でもあります。適切な応答が得られたと仮定すると、データはEndXXX呼び出しから返され、意味のある方法でそのデータに反応できます。

注:このパターンについて覚えておくべきことの 1 つは、スレッドの性質です。WCF からの非同期コールバックは、マネージド スレッド プールのスレッドで受信されます。InvokeWPF や WinForms などのテクノロジで UI を更新することを計画している場合は、またはBeginInvokeメソッドを使用して UI スレッドへの呼び出しをマーシャリングする必要があります。

サーバー上で効率的であること

クライアントの効率を心配するつもりなら、サーバーに関しては二重に心配する必要があります。明らかに、このタイプのアプローチでは、クライアントに通知を送り返す理由が生じるまで、接続を開いたままにして保留にする必要があるため、サーバー側により多くの要求が課せられます。ここでの課題は、WCF ランタイムを、実際にイベントが送信されているクライアントの処理だけに結び付けたいということです。他のすべては、イベントが発生するのを待って、スリープ状態にする必要があります。幸いなことに、クライアント側で使用したのと同じ非同期パターンがサーバー側でも機能します。ただし、大きな違いがありますIAsyncResult。メソッドから(したがって、WaitHandle) を返す必要がBeginXXXあり、WCF ランタイムは、メソッドを呼び出す前にシグナルが送信されるのを待機します。EndXXX方法。

以前に提供したリンク以外の MSDN 内のドキュメントの方法はあまり見つかりません。残念ながら、非同期サービスの作成に関するサンプルはあまり役に立ちませ。とは言うものの、ウェンロン ドンは、非同期モデルを使用した WCF サービスのスケーリングに関する記事を書いています。

これを超えて、正直なところ、サーバー側で非同期モデルを実装する最善の方法についてあまりアドバイスすることはできません。なぜなら、そもそもイベントがどのような種類のデータ ソースから来るのかに完全に依存するからです。ファイル I/O? メッセージキュー? データベース?ファサードを提供しようとしている、独自のメッセージング サービスを備えた他のプロプライエタリ ソフトウェアはありますか? わかりませんが、それらはすべて独自の非同期モデルを提供する必要があり、独自のサービスをピギーバックして可能な限り効率的にすることができます。

処方箋の更新

これはよくある回答のように思われるので、ここに戻って状況の最近の変化を踏まえて最新情報を提供する必要があると考えました。この時点で、この正確な機能を提供するSignalRと呼ばれる .NET ライブラリがあり、サーバーとのそのような通信を実装することをお勧めします。

于 2009-11-17T03:53:55.853 に答える
2

WCF ではありませんが、XMPP を使用してその機能を実現することができます。それと他のシステムに関するInfoQの記事があります。この記事では、XMPP は HTTP 経由では使用できないと述べていますが、BOSHを使用すると使用できます。

1 つを挙げると、 agsXMPPを使用できる .NET ライブラリがあります。

私が働いている会社は、ユーザー インターフェイスの一部を更新するためにアプリケーションに更新通知をプッシュするためにそれを使用し始めています。

于 2009-11-12T13:12:25.247 に答える
1

「 WCFデュプレックス」のGoogle 。私はこれをnetTcpBinding(大陸全体)を使用して正常に使用しましたが、basicHttpBindingについてはよくわかりません。

ただし、サーバーがクライアントにコールバックする必要があります。サーバーがこれを行うことを許可されていない場合は、ポーリングが唯一のオプションである可能性があります...

于 2009-11-09T13:23:38.593 に答える
0

サーバーがクライアントを呼び出せない場合(通常は呼び出さないはずです)、指定したとおりにクライアントがサーバーをポーリングする必要があります。WCFの基盤がすでに整っているので、そのための操作を追加するだけです。

于 2009-11-09T13:21:08.980 に答える