且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

【Netty】Netty 核心组件 ( ChannelPipeline 中的 ChannelHandlerContext 双向链表分析 )(一)

更新时间:2021-08-13 10:53:25

一、 代码示例分析


1 . 基于以下代码分析 :


// 1. 之前创建 bossGroup workerGroup 两个线程池 
// 省略一万行代码 ...
// 2. 服务器启动对象, 需要为该对象配置各种参数
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup) // 设置 主从 线程组 , 分别对应 主 Reactor 和 从 Reactor
        .channel(NioServerSocketChannel.class)  // 设置 NIO 网络套接字通道类型
        .option(ChannelOption.SO_BACKLOG, 128)  // 设置线程队列维护的连接个数
        .childOption(ChannelOption.SO_KEEPALIVE, true)  // 设置连接状态行为, 保持连接状态
       
        // 核心分析代码 ------------------------------------------------------------------------
        .childHandler(  // 为 WorkerGroup 线程池对应的 NioEventLoop 设置对应的事件 处理器 Handler
                new ChannelInitializer<SocketChannel>() {// 创建通道初始化对象
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        // 该方法在服务器与客户端连接建立成功后会回调
                        // 获取管道
                        ChannelPipeline pipeline = ch.pipeline();
                        // 为管道加入 HTTP 协议的编解码器 HttpServerCodec,
                        // codec 中的 co 是 coder 编码器的意思, dec 是 decoder 解码器的意思
                        // 第一个字符串是编解码器的名称
                        pipeline.addLast("HttpServerCodec" , new HttpServerCodec());
                        // 为管道 Pipeline 设置处理器 Hanedler
                        pipeline.addLast("HTTPServerHandler", new HTTPServerHandler());
                        // 管道初始化完成
                        // 在此行代码上打断点 ----------------------------------------------
                        System.out.println("管道初始化完成!");
                    }
                }
             
        );
         // 核心分析代码 ------------------------------------------------------------------------





2 . 元素类型 :



① 头尾元素 : 双向链表的头尾都是自动生成的 , 其类型是 DefaultChannelPipeline , 头尾元素中没有封装 Handler 处理器 ;


② 中间元素 : 双向链表的中间元素是 DefaultChannelHandlerContext 类型的 , 封装了 Handler 处理器 ;




3 . 双向链表元素内封装的 ChannelHandler 类型 : 从头元素之后的第一个元素开始到最后一个元素之间 , 每个双向链表中的元素都封装有一个 ChannelHandler ;




4 . ChannelPipeline 管道中 , 放入了 3 33 个 Handler 处理器 ;



① ChannelInitializer : 通道初始化器 ;


② HttpServerCodec : HTTP 服务器编解码器 ;


③ HTTPServerHandler : 用户自定义的 HTTP 服务器业务逻辑处理器 ;




5 . ChannelPipeline 管道添加 ChannelHandler 处理器 :



① addFirst : 将 ChannelHandler 处理器添加到双向链表的表头 ;


ChannelPipeline addFirst(String name, ChannelHandler handler);
ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);


② addLast : 将 ChannelHandler 处理器添加到双向链表的尾部 ;


ChannelPipeline addLast(String name, ChannelHandler handler);
ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);





二、 ChannelHandlerContext 双向链表类型


1 . 表头元素和表尾元素类型 : 双向链表的表头元素和表尾元素都是 DefaultChannelPipeline 类型的 , 该类型没有封装 ChannelHandler 处理器 ;



2 . 双向链表中间类型 : 表头表尾中间类型是 DefaultChannelHandlerContext 类型的 , 该类型中封装了 ChannelHandler 处理器 ;



3 . ChannelHandlerContext 类型 :


final class DefaultChannelHandlerContext extends AbstractChannelHandlerContext {
    private final ChannelHandler handler;
   
    DefaultChannelHandlerContext(
            DefaultChannelPipeline pipeline, EventExecutor executor, String name, ChannelHandler handler) {
        super(pipeline, executor, name, isInbound(handler), isOutbound(handler));
        if (handler == null) {
            throw new NullPointerException("handler");
        }
        this.handler = handler;
    }
    @Override
    public ChannelHandler handler() {
        return handler;
    }
    private static boolean isInbound(ChannelHandler handler) {
        return handler instanceof ChannelInboundHandler;
    }
    private static boolean isOutbound(ChannelHandler handler) {
        return handler instanceof ChannelOutboundHandler;
    }
}





三、 Pipeline / ChannelPipeline 管道内双向链表分析


0 . 双向链表表头 head ( 第 0 00 个元素 ) : 打开 head 元素的成员 , 查看其成员组成 ;



① prev 为空 : 这是双向链表的表头 , 因此其 prev 元素 ( 前一个元素 ) 是空的 ;


② next 元素 : 查看其下一个元素 , 其下一个元素肯定也是 ChannelHandlerContext 类型的 ;


③ 开始表头元素类型 : DefaultChannelPipeline ;

【Netty】Netty 核心组件 ( ChannelPipeline 中的 ChannelHandlerContext 双向链表分析 )(一)



1 . 双向链表第 1 11 个元素 Handler 类型 : 其 Handler 是 HTTPServer 中的匿名内部类 ChannelInitializer , 也就是创建的 ChannelInitializer 匿名内部类 ;


第 1 11 个元素 Handler 类型 : ChannelInitializer , 该类继承了 ChannelInboundHandlerAdapter , 因此也是一个处理器 Handler ;


public abstract class ChannelInitializer<C extends Channel> extends ChannelInboundHandlerAdapter


【Netty】Netty 核心组件 ( ChannelPipeline 中的 ChannelHandlerContext 双向链表分析 )(一)




2 . 双向链表第 2 22 个元素 Handler 类型 : 其 Handler 是 HttpServerCodec 类型的对象, 也就是为 ChannelPipeline 添加的 HttpServerCodec 编解码器 ;


第 2 22 个元素 Handler 类型 : HttpServerCodec ;


// 获取管道
ChannelPipeline pipeline = ch.pipeline();
// 本次示例核心代码 ---------------------------------------------
// 为管道加入 HTTP 协议的编解码器 HttpServerCodec,
// codec 中的 co 是 coder 编码器的意思, dec 是 decoder 解码器的意思
// 第一个字符串是编解码器的名称
pipeline.addLast("HttpServerCodec" , new HttpServerCodec());
// 本次示例核心代码 ---------------------------------------------

【Netty】Netty 核心组件 ( ChannelPipeline 中的 ChannelHandlerContext 双向链表分析 )(一)