1

我有一个基于 TCP 的 Netty 应用程序,其中有多个需要相互通信的客户端。我将所有 Channel 引用存储在 ChannelGroup 中。

虽然我知道我可以通过调用 ChannelGroup.write 向 ChannelGroup 中的每个客户端写入数据,但是除了其中一个通道之外,写入所有通道的有效方法是什么,例如:

'A','B','C'一起在一个Channel Group中,'A'需要发送给'B'和'C','B'需要发送给'A'和'C'等等。最好的方法是什么?以下是我想到的一些选项,但我们将不胜感激:

  1. 只需遍历 Group 并单独写入通道(在这种情况下不要使用 ChannelGroup.write)

  2. 反复“重新制作/克隆” ChannelGroup,使其仅包含要写入的通道。然后我会在修改后的组上调用 ChannelGroup.write,然后将该组恢复为完整组。

  3. 写入所有通道,但实现一些处理程序逻辑以丢弃(在编码或下游处理程序上)并且如果消息来自排除的通道,则不写入消息。

就设计权衡而言,消息尽可能快地发送,ChannelGroups 相对较小,<20 个通道,每个消息的大小约为 1kb(500 字节 - 2kb)。此外,如果不同的逻辑对本地主机反馈效果更好,那么在这种情况下,许多连接与服务器位于同一主机上,我们将不胜感激。

非常感谢您的帮助!

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

....虽然您确实获得了多路复用未来的好处,但如果您关心完成回调,这很有用。

我也不会做#3,因为你只是给下游处理程序更多的工作要做,丢弃你一开始就费心写的数据。

所以我要么:

  1. 实施选项#1
  2. 扩展 DefaultChannelGroup 并添加一个足够聪明的 write 方法来跳过相关通道。将频道添加到组时,您可能需要提供更多元数据。
于 2012-05-08T21:26:03.360 回答