在使用Netty4时对连接进行关闭时通过会使用ctx.close和ctx.channel.close两个方法,使用示例如下:

private void illegalClient(ChannelHandlerContext ctx) {
    ctx.channel().close();
    ctx.close();
}

那么这两个close方法的调用有什么区别呢?

假设我们有三个handler在pipeline中,它们都监听close()方法的操作,并调用ctx.clouse(),实例如下:

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(),然后关闭channel。

第二,ChannelPipeline.context(“C”).close()会触发B.close(),A.close(),然后关闭channel。

第三,ChannelPipeline.context(“B”).close()会触发A.close(),然后关闭channel。

第四,ChannelPipeline.context(“A”).close(),会关闭channel,不会关闭handler。

那么,什么时候应该使用Channel.close()和ChannelHandlerContext.close()?基本规则如下:

如果你在当前的ChannelHandler中操作,并想关闭当前channel,那么调用ctx.close()。

如果你在当前handler外部关闭channel,比如后台线程并不是一个i/o线程,你想从那个线程关闭channel。

其中,ctx.close()从ChannelHandlerContext开始流经ChannelPipeline,而ctx.channel()。close()则始终从ChannelPipeline的尾部开始。



Netty4 ctx.close和ctx.channel.close的区别插图

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:https://choupangxia.com/2021/02/03/netty4-ctx-close/