В Netty 4, какая разница между ctx.close и ctx.channel.close?

Есть ли разница? Является ли ctx.close более короткой версией ctx.channel.close?

Ответ 1

Скажем, у нас есть три обработчика в конвейере, и все они перехватывают операцию close() и вызывают в ней ctx.close().

ChannelPipeline p = ...;
p.addLast("A", new SomeHandler());
p.addLast("B", new SomeHandler());
p.addLast("C", new SomeHandler());
...

public class SomeHandler extends ChannelOutboundHandlerAdapter {
    @Override
    public void close(ChannelHandlerContext ctx, ChannelPromise promise) {
        ctx.close(promise);
    }
}
  • Channel.close() вызовет C.close(), B.close(), A.close(), а затем закроет канал.
  • ChannelPipeline.context("C").close() вызовет B.close(), A.close(), а затем закроет канал.
  • ChannelPipeline.context("B").close() вызовет A.close(), а затем закроет канал.
  • ChannelPipeline.context("A").close() закроет канал. Обработчики не будут вызываться.

Итак, когда вы должны использовать Channel.close() и ChannelHandlerContext.close()? Эмпирическое правило:

  • Если вы пишете ChannelHandler и хотите закрыть канал в обработчике, вызовите ctx.close().
  • Если вы закрываете канал снаружи обработчика (например, у вас есть фоновый поток, который не является потоком ввода-вывода, и вы хотите закрыть соединение с этим потоком.)

Ответ 2

ctx.close() начинает протекать через ChannelPipeline с точки ChannelHandlerContext, а ctx.channel(). close() будет начинаться с хвоста ChannelPipeline все время.