如果我在写完回复后立即关闭频道会发生什么?回复是否仍送达?
这个http上传示例似乎是这样说的,但我不确定这是否只是一个错误。
writeResponse(ctx.channel());
ctx.channel().close();
如果您.close()
在写入后立即关闭通道,那么您将创建一个竞争条件,其中所有数据都已写入,一半数据,甚至没有,具体取决于消息的长度。
发生这种情况是因为所有写入的消息最终都进入一个队列,并且取决于当前线程是否是 Netty 线程,它要么处理数据目录,要么只是返回。
由于在大多数情况下,您只想在所有写入完成后关闭通道,因此在编写响应时应使用以下代码:
ctx.writeAndFlush(protocolSpecificPacket)
.addListener(ChannelFutureListener.CLOSE);
虽然这总是有效,但您并不总是可以访问最后一次写入,在这些情况下,您也可以发送一个 empty ByteBuf
,然后将侦听器添加到其中:
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
.addListener(ChannelFutureListener.CLOSE);
不,这不是错误,但不是关闭频道的最佳方式,我假设您 writeResponse 执行如下:
ctx.channel().write(msg)
它是异步发送的,实际上消息将提供给 writeBufferQueue,并且写入 IO 线程将被唤醒以进行实际写入。
检查ChannelFuture
ctx.channel().write(msg) 返回的,你可以等待那个对象。
我认为关闭网络频道的最佳方法是:
ctx.channel().write(a emptybuffer).addFutureListener(Channels.CloseFuture);
由于您使用的是 netty 4.0,您可能需要搜索与上述类似的内容。