1

以下で示唆されているテクニックを使用します。

http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.callbackcontract.aspx

API に ServerPush セットアップを実装して、イベント サーバーからリアルタイム通知を取得します (ポーリングなし)。基本的に、サーバーには RegisterMe() および UnregisterMe() メソッドがあり、クライアントには、WCF の CallbackContract メカニズムを介して呼び出すことができる Announcement(string message) というコールバック メソッドがあります。これはうまくいくようです。

残念ながら、このセットアップでは、サーバーがクラッシュしたり、それ以外の理由で利用できなくなったりしても、クライアントはメッセージをリッスンしているだけなのでわかりません。回線の無音は、アナウンスがないことを意味する場合もあれば、サーバーが利用できないことを意味する場合もあります。

私の目標は即時性ではなくポーリングを減らすことであるため、サーバーへの接続をテストするためだけに存在する RegisterMe() および UnregisterMe() と一緒にサーバーに void Ping() メソッドを追加してもかまいません。このメソッドを定期的にテストすることで、まだ接続されていることを確認できます (また、これは TCP であるため、トランスポートによってアナウンスが破棄されていないことも確認されます)。

しかし、Ping() メソッドが必要ですか、それともこの接続テストは、serverProxy.IsStillConnected() などのように、デフォルトで WCF の一部として利用可能ですか? 私が理解しているように、チャネルの状態は、失敗した Ping() の後にのみ Faulted または Closed を返しますが、代わりには返しません。

2) より広い観点から、このコールバック アプローチは堅実ですか? これは http や ajax 用ではありません。接続されているクライアントの数は少なくなります (最大で数十のクライアント)。このアプローチに深刻な問題はありますか? これは軽度のリスクと思われるため、コールバック キューを十分に高速に処理しないことで、低速/悪意のあるクライアントがサーバーをブロックするのを制限するにはどうすればよいですか? 他の操作に影響を与えずに設定できる、コールバック固有のタイムアウトのようなものはありますか?

4

3 に答える 3

2

あなたのアプローチは合理的に聞こえます.ここに役立つかもしれないし、役に立たないかもしれないいくつかのリンクがあります(それらは完全に関連しているわけではありません):

WCF デュプレックス コントラクトでのクライアントの死の検出 http://tomasz.janczuk.org/2009/08/performance-of-http-polling-duplex.html

アプリケーション プロトコルにヘルス チェックを組み込むことは理にかなっています。

悪意のあるクライアントが心配な場合は、承認を追加してください。

上記で共有した 2 番目のリンクには、サンプルの pub/sub サーバーがあり、このコードを使用できる場合があります。注意すべき点がいくつかあります。非同期呼び出しまたは別のスレッドで通知をプッシュすることを検討してください。そして、tcp バインディングで sendTimeout を設定します。

HTH

于 2009-11-07T05:02:52.767 に答える
1

WCFアプリケーションを作成しましたが、同様の問題が発生しました。私のサーバーは、定期的にpingを送信して、クライアントが「プラグプル」されていないことを確認しました。実際のsendメソッド(サーバーであるため非同期でした)のタイムアウトは30秒でした。クライアントは、30秒ごとにデータを受信したことを確認するだけでしたが、タイムアウトに達した場合、サーバーは例外をキャッチしました。

サーバーに接続するには(接続者が最初に特定のメソッドを呼び出すように強制するWCFの組み込み機能を使用して)承認が必要だったため、悪意のあるクライアントの観点から、アカウントをチェックして禁止するコードを簡単に追加できます。認証されていないユーザーを切断しているときに、何か疑わしいことがあります。

私が書いたサーバーは非同期だったので、それを実際にブロックする方法はありませんでした。非同期のsendメソッドがping(およびその他のデータの送信)を起動してすぐに戻るので、これは最後のポイントに対処していると思います。SendEndメソッドでは、サーバーをブロックしたりフリーズしたりすることなく、タイムアウト例外(クライアントでは複数の場合もあります)をキャッチして切断します。

お役に立てば幸いです。

于 2009-11-10T12:10:34.577 に答える
1

Juval によって提案されたものと同様のパブリッシャー/サブスクライバー サービスを使用できます: http://msdn.microsoft.com/en-us/magazine/cc163537.aspx

これにより、サーバーの損失が一般的なシナリオである場合に、サブスクライバーを永続化できます。この例の publish メソッドは、個別のスレッドで各サブスクライバーも呼び出すため、いくつかのデッド サブスクライバーは他のサブスクライバーをブロックしません...

于 2009-11-11T18:18:42.183 に答える