2016-07-15 34 views
0

的Netty 4.1.2.Final的Netty 4:在包裹缓冲引用计数

我使用Unpooled.wrappedBuffer方法来包装多于一个ByteBuf S,API文档是here

public static ByteBuf wrappedBuffer(ByteBuf... buffers) 

的医生说

所有变量的引用计数所有权转移到这种方法。

我更新了问题,以便更清楚。

我需要一次发送多个ByteBuf s到多个连接。 我不能使用ChannelGroup,因为有些客户端在长轮询模式下工作,这意味着响应必须在下一个请求中发送,其请求的通道此时尚未准备好。

因此,我有下面的数据结构存储所连接的通道

private static final ConcurrentHashMap<String, Channel> channels 
    = new ConcurrentHashMap<String, Channel>(); 

我不得不广播ByteBuf于通道

public static void broadcast(final long registrationID, final ByteBuf [] buffers){ 
    final ByteBuf wrappedBuf = Unpooled.wrappedBuffer(buffers); 
    for(Map.Entry<String, Channel> entry : channels.entrySet()){ 
    final Channel channel = entry.getValue(); 
    if(channel != null){ 
     wrappedBuf.retain(); 

     boolean isLongPooling = channel.attr(TYPE).get(); 
     if(isLongPooling) 
      Reply.send(channel, wrappedBuf); // add into a queue which will be pulled by client in next request 
     else 
      channel.writeAndFlush(wrappedBuf); // real time client , send in current channel 
    } 
    } 
    wrappedBuf.release(); 
} 

该问题的方法是,如果我有多个实时客户端连接,即使全部都写入,其中只有一个接收到响应。

现在看来,这是造成引用计数的问题吗?

谢谢

+0

原因是没有引用计数,它是由一些句柄引起的修改'ByteBuf'。因此只有第一个连接接收。解决方案是在ByteBuf之后添加'asReadOnly()'。 –

回答

1

不......这意味着你需要在返回的缓冲区上调用release()。

+0

如果我需要调用'release()',这意味着输入'ByteBuf'被保留了吗?否则,为什么我需要调用'release()'如果引用计数没有改变? –

+1

因为如果你打包缓冲区,你应该在新返回的缓冲区上调用release(),而不是在刚刚打包的缓冲区上。 –

+0

从我的测试来看,它不会那样工作。如果我不调用原来的“ByteBuf”的“保留”,则会发生“IllegalReferenceCountException”。如果我调用wrap的ByteBuf的'retain',它不会改变底层'ByteBuf'的引用计数。 –