我尝试使用Netty 4.0.25实现流式传输并进行此设置(减少伪代码)。我的意图是尽可能避免复制,我也使用ChunkedWriteHandler
进行了探索,但它似乎不适合我的用例。
public ResponseChannel implements WritableByteChannel {
@Override
public int write(ByteBuffer src) {
int bytesWritten = src.remaining();
ByteBuf buf = Unpooled.wrappedBuffer(src);
ctx.writeAndFlush(new DefaultHttpContent(buf));
return bytesWritten;
}
}
目前,让我们忽略频道可写性,并假设如果我们写src.remaining()
我们就不会去OOM,并且在将来也会忽略写入失败(这是减少的代码,我处理所有这些案例都在较长的版本中。)
由于我在这里包装src
,ByteBuf
也使用了相同的底层字节,我不应该在字节实际发送之前更改它。所以我的问题是,src
何时可以重复使用?马上?或者我应该将一个监听器附加到写入的未来,并在监听器的operationComplete()
被调用时将其标记为可重用?
如果它不能立即重用,那么返回bytesWritten
的语义也是错误的(因为调用者总是在返回时清除ByteBuffer
并在原始字节之前写入新数据写入网络)。
我的管道是
ch.pipeline()
.addLast("codec", new HttpServerCodec())
.addLast("idleStateHandler", new IdleStateHandler(0, 0, 10))
.addLast("processor", new NettyMessageProcessor());`
我已经对传输编码进行了分块,据我所知HttpObjectEncoder
,在分块编码的情况下不会创建副本(如果没有分块编码,就会创建一个副本,所以如果我没有& #39; t具有分块传输编码 - src
可用于立即重用)。
答案 0 :(得分:2)
诺曼在Netty讨论谷歌小组回答了这个问题。
TL; DR版本是src
中的字节被认为是免费的,直到调用写入operationComplete()
的{{1}} ChannelFutureListener
为止。< / p>
讨论谷歌小组here。