Netty:Shoud我创建了新的ChannelBuffer来向每个客户端发送数据?

时间:2018-02-08 04:20:41

标签: java netty

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

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

我想向他们发送像&#34; Hello&#34;串。我正在创建一个包含这些数据的新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对象。

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

ChannelBuffers.wrappedBuffer()