【问题标题】:Netty: Shoud i create new ChannelBuffer for sending data to every client?Netty:我应该创建新的 ChannelBuffer 来向每个客户端发送数据吗?
【发布时间】:2018-02-08 04:20:41
【问题描述】:

我有一个连接的客户端列表,例如 SimpleChannelHandler:

List<ChannelHandler> clients = new ArrayList<ChannelHandler>();

我想向他们发送诸如“Hello”字符串之类的数据。我正在创建一个包含此数据的新 ChannelBuffer:

ChannelBuffer cb = ChannelBuffers.buffer(1024);
cb.writeBytes("Hello".getBytes());

然后我想将此数据发送给所有连接的客户端。问题是 - 我可以只使用这个通道缓冲区将这些数据发送给所有客户端,还是应该为每个客户端创建一个新的通道缓冲区? 我问是因为据我所知,在调用 channel.write(cb) 操作之后 - ChannelBuffer 写入索引会改变,我怀疑相同的缓冲区是否会正确发送到下一个客户端。

所以,有两种方法。第一个,只向所有客户端发送一个 ChannelBuffer:

 ChannelBuffer cb = ChannelBuffers.buffer(1024);
 cb.writeBytes("Hello".getBytes());
 for(ChannelHandler ch : clients)
   ch.write(cb)

第二个,为每个客户端创建一个新的ChannelBuffer:

for(ChannelHandler ch : clients) {
  ChannelBuffer cb = ChannelBuffers.buffer(1024);
  cb.writeBytes("Hello".getBytes());
  ch.write(cb)
}

哪种方式正确?

更新:

我做了一些测试,可以说第一种方法行不通。在第一次发送 ChannelBuffer 后,channel.write 操作会将 writerIndex 重置为零,所有下一个客户端都不会得到任何信息。 要在不使用第二种方式的情况下解决此问题,需要做一些变通方法:

ChannelBuffer cb = ChannelBuffers.buffer(1024);
cb.writeBytes("Hello".getBytes());
cb.markWriterIndex();
for(ChannelHandler ch : clients) {
  cb.resetWriterIndex();
  ch.write(cb);
}

第二种方式也可以,但它会在每次写入之前创建一个新的 ChannelBuffer 对象。

【问题讨论】:

    标签: java netty


    【解决方案1】:

    两种方式都是正确的。您也可以复制ChannelBuffer,这样您就不必每次都复制cb.writeBytes

    但是,我建议您使用StringEncoder,这样您就可以将String 直接写入频道,这样您就不必考虑ChannelBuffer

    【讨论】:

    • 感谢 Dmitriy 的回答。我测试了两种方式并更新了第一篇文章。似乎“纯”视图中的第一种方式不能用于广播消息,我在第一篇文章中添加了一些细节。
    • 我的错。我以为你只是发送 byte[] 而不是 ChannelBuffer 在第一种情况下。您使用 resetWriterIndex(); 的方法;可能是错的。由于客户端通道可能位于不同的 EventLoops 中,这可能会给您带来并发问题。但是,这取决于 ChannelBuffer 的实现。
    • 当客户端从不同的EventLoops调用发送代码时,可以使用哪种方法来解决这种情况?为每个客户端创建新的 ChannelBuffer 实例?
    • 是的。您可以查看 DefaultChannelGroup,它也是缓冲区的副本。
    【解决方案2】:

    如果您要将相同(不可变)内容广播到多个内容,请考虑使用ChannelBuffers.wrappedBuffer()。这会创建底层字节数组的包装视图,您可以将一个视图分发给每个客户端,而不会产生复制开销。

    byte[] data = "Hello".getBytes();
    for(ChannelHandler ch : clients) {
        ChannelBuffer cb = ChannelBuffers.wrappedBuffer(data);
        ch.write(cb)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-10
      • 1970-01-01
      • 2015-04-07
      • 2014-02-07
      • 2016-05-13
      • 2017-10-26
      • 2012-03-04
      • 1970-01-01
      相关资源
      最近更新 更多