Netty之DefaultChannelPipeline源码分析

本文深入探讨了Netty中DefaultChannelPipeline的工作原理,包括初始化过程、Handler的添加方式及ChannelHandlerContext的双向链表结构。详细解析了Head和Tail在入站和出站操作中的角色,以及Unsafe类如何执行具体的IO操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DefaultChannelPipeline类在初始化时,会创建两个ChannelHandlerContext实例,一个为head,一个为tail。Head为头部,Tail为尾部。其实给ChannelPipeline添加handler是,都是封装成一个ChannelHandlerContext再添加至channelpipeline, 所以实际上pipeline维护的一个有ChannelHandlerContext的双向链表,头为Head, 尾部为Tail.

在这里插入图片描述

Head跟Tail是两个很重要的HandlerContext.

head

所有出站的操作最后都是通过head来实现具体io操作。head同时实现了inbount与outbound两个接口,所以所有入站操作第一个是到达head,所有出站操作最后一个到达head



@Override
        public void bind(
          ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception {
            unsafe.bind(localAddress, promise);
        }

最后由channel的unsafe内部类执行具体的IO操作(unsafe会使用java nio的api完成操作)。其他的IO操作还有connect,disconnect,close,deregister,read,write,flush。

对于入站操作,head也提供了实现,在往后传event的基础上,不同的event会有一些额外的操作。

@Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            ctx.fireChannelActive();

            readIfIsAutoRead();
        }
@Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            ctx.fireChannelActive();

            readIfIsAutoRead();
        }

        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {
            ctx.fireChannelInactive();
        }

tail

tail这个ChannelHandlerContext实现了ChannelInboundHandler接口,左右最后一个inboundHandler, 基本上是吞掉所有消息,一些接口会做消息的释放。

@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception { }

@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { }

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
            onUnhandledInboundChannelActive();
        }

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            onUnhandledInboundMessage(msg);
        }
protected void onUnhandledInboundMessage(Object msg) {
        try {
            logger.debug(
                    "Discarded inbound message {} that reached at the tail of the pipeline. " +
                            "Please check your pipeline configuration.", msg);
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

channelpipeline

channelpipeline提供了bind,connect,disconnect,close,deregister,flush,write,writeAndFlush等操作,这些操作都是调用tail的对应同名方法(将event传到下一个outboundhandler),最后到达head,head再使用unsafe来执行相应的操作。

@Override
    public final ChannelFuture bind(SocketAddress localAddress) {
        return tail.bind(localAddress);
    }

对于入站操作,channelpipeline都是提供fireXXX的接口,从head开始往后传。

@Override
    public final ChannelPipeline fireChannelActive() {
        AbstractChannelHandlerContext.invokeChannelActive(head);
        return this;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值