写入响应后立即关闭通道

ali*_*ice 4 java netty

如果我在写入响应后立即关闭通道会发生什么?是否仍然提供响应?

这个http 上传示例似乎是这样说的,但我不确定它是否只是一个错误。

writeResponse(ctx.channel());
ctx.channel().close();
Run Code Online (Sandbox Code Playgroud)

Fer*_*big 5

如果您.close()在写入后立即使用关闭通道,那么您将创建一个竞争条件,其中要么写入所有数据,要么写入一半数据,甚至不写入,具体取决于消息的长度。

发生这种情况是因为所有写入的消息最终都会进入一个队列,并且取决于当前线程是否为 Netty 线程,它要么处理数据目录,要么直接返回。

由于在大多数情况下您只想在所有写入完成后关闭通道,因此在编写响应时应使用以下代码:

ctx.writeAndFlush(protocolSpecificPacket)
    .addListener(ChannelFutureListener.CLOSE);
Run Code Online (Sandbox Code Playgroud)

虽然这总是有效,但您并不总是可以访问最后一次写入,在这些情况下,您也可以发送一个空的ByteBuf,然后将侦听器添加到其中:

ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
    .addListener(ChannelFutureListener.CLOSE);
Run Code Online (Sandbox Code Playgroud)


Bla*_*ker 0

不,这不是一个错误,但不是关闭通道的最佳方法,我假设你 writeResponse 执行如下:

ctx.channel().write(msg)
Run Code Online (Sandbox Code Playgroud)

它是异步发送的,实际上消息将提供给 writeBufferQueue,并且写入 IO 线程将被唤醒以进行实际写入。

检查ChannelFuturectx.channel().write(msg) 返回的内容,您可以等待该对象。

我认为关闭 netty 通道的最佳方法是:

ctx.channel().write(a emptybuffer).addFutureListener(Channels.CloseFuture);
Run Code Online (Sandbox Code Playgroud)

由于您使用的是netty 4.0,您可能需要搜索与上面类似的内容。