1

相互に通信する必要のある複数のクライアントを備えたTCPベースのNettyアプリケーションがあります。すべてのチャネル参照をChannelGroupに保存します。

ChannelGroup.writeを呼び出すことで、ChannelGroup内のすべてのクライアントに書き込むことができることはわかっていますが、これらのチャネルの1つを除くすべてに書き込むための効率的な方法は次のようになります。

「A」、「B」、「C」は一緒にチャネルグループにあり、「A」は「B」と「C」に送信する必要があり、「B」は「A」と「C」に送信する必要があります。これを行うための最良の方法は何でしょうか?これが私が考えたいくつかのオプションですが、いくつかのフィードバックをいただければ幸いです。

  1. グループを繰り返し処理し、チャネルに個別に書き込みます(この場合はChannelGroup.writeを使用しないでください)

  2. ChannelGroupを繰り返し「リメイク/クローン」して、書き込み先のチャネルのみが含まれるようにします。次に、変更したグループでChannelGroup.writeを呼び出し、グループを完全なグループに復元します。

  3. すべてのチャネルに書き込みますが、(エンコードまたはダウンストリームハンドラーのいずれかで)破棄するハンドラーロジックを実装し、除外されたチャネルからのメッセージの場合はメッセージを書き込みません。

設計上のトレードオフに関する限り、メッセージは可能な限り迅速に送信され、ChannelGroupsは比較的小さく<20チャネルであり、メッセージのサイズはそれぞれ約1kb(500バイト-2 kb)です。また、異なるロジックがローカルホストのフィードバックに対してより適切に機能する場合、接続の多くがサーバーと同じホスト上にあるというシナリオがあります。

助けてくれてありがとう!

4

1 に答える 1

3

私は#2をしません。私の知る限り、チャネルグループへの書き込みに固有のパフォーマンス上の利点はありません。DefaultChannelGroupのコードを見ると、登録されたチャネルを繰り返し処理し、書き込みを発行して先物を収集します。

public ChannelGroupFuture write(Object message) {
         Map<Integer, ChannelFuture> futures =
             new LinkedHashMap<Integer, ChannelFuture>(size());
         if (message instanceof ChannelBuffer) {
             ChannelBuffer buf = (ChannelBuffer) message;
             for (Channel c: nonServerChannels.values()) {
                 futures.put(c.getId(), c.write(buf.duplicate()));
             }
         } else {
             for (Channel c: nonServerChannels.values()) {
                 futures.put(c.getId(), c.write(message));
             }
         }
         return new DefaultChannelGroupFuture(this, futures);
     }

....多重化されたfutureの利点はありますが、完了コールバックを気にする場合は便利です。

ダウンストリームハンドラーにもっとや​​るべき仕事を与えているだけなので、#3もしません。そもそも、わざわざ書き込みに行ったデータを破棄します。

だから私はどちらかだろう:

  1. オプション#1を実装する
  2. DefaultChannelGroupを拡張し、問題のチャネルをスキップするのに十分賢い書き込みメソッドを追加します。グループにチャネルを追加するときは、おそらくもう少しメタデータを提供する必要があります。
于 2012-05-08T21:26:03.360 に答える