【Netty】Netty 核心组件 ( Pipeline | ChannelPipeline )





一、 Pipeline / ChannelPipeline 管道组件



1 . ChannelPipeline 本质及作用 :


① ChannelPipeline 本质 : ChannelPipeline 是负责业务逻辑的处理器 ChannelHandler 的集合 ;

② ChannelPipeline 作用 : 拦截 入站 ( Inbound ) 和 出站 ( Outbound ) 的 IO 事件 , 并进行相应的业务逻辑处理 ;


ChannelPipeline 是 Handler 集合 , 处理 入站 / 出站 操作 ;



2 . ChannelPipeline 过滤器模式 : ChannelPipeline 设计中使用了过滤器模式 , 基于该过滤器模式的机制 , 用户可以拦截 IO 事件 , 并进行自己的业务逻辑操作 , 拦截 IO 事件 , 使用该 ChannelPipeline 对象的 Channel 通道中的 ChannelHandler 中处理业务逻辑 ;



3 . ChannelPipeline 相关组件的对应关系 :


① 管道与通道 : 每个 ChannelPipeline 管道对应一个 Channel 通道 , ChannelPipeline 与 Channel 两者是 1 : 1 1:1 1:1 的关系 ;

② 管道与处理器 : 每个 ChannelPipeline 管道中维护了处理器 ChannelHandler 集合 , 管道 ChannelPipeline 与 处理器 Handler 两者是 1 : n 1:n 1:n 的关系 ;

③ 处理器与处理器上下文 : 每个 ChannelHandler 处理器都有一个与之对应的 ChannelHandlerContext , 二者是 1 : 1 1:1 1:1 的关系 ;

④ 处理器上下文链表 : 管道中的 ChannelHandler 处理器是放在一个集合中的 , 每个与 ChannelHandler 对应的 ChannelHandlerContext 是放在一个双向链表中 ;

⑤ 图示 : 下图可以描述 Channel 管道 , ChannelPipeline 管道 , ChannelHandlerContext 通道处理器上下文 , ChannelHandler 处理器的对应关系及结构 ;

在这里插入图片描述





二、 Pipeline / ChannelPipeline 管道组件元素解析



1 . Debug 调试查看管道内部元素 : 任意找一个 Netty 服务器程序 , 绑定端口后 , 获取一下 ChannelPipeline , 然后 Debug 调试查看 ChannelPipeline 中的元素结构 ;



2 . 代码及断点 : 运行 【Netty】使用 Netty 开发 HTTP 服务器 | 三、 HTTP 服务器代码实现 中的 HTTP 服务器代码 , 在 ServerBootstrap 配置中的 childHandler 设置 ChannelInitializer 最后一行代码打断点 ;

这里只列举部分代码 , 在获取 ChannelPipeline 代码处打上断点 , 查看其内部元素

// 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("管道初始化完成!");
                    }
                }
               
        );
         // 核心分析代码 ------------------------------------------------------------------------

在这里插入图片描述



3 . 运行程序进入断点 :


① 运行服务器端程序 : 使用 debug 模式运行服务器程序

在这里插入图片描述

② 浏览器访问服务器 : 浏览器访问 http://127.0.0.1:8888 地址 , 此时代码执行进入断点位置 ;

在这里插入图片描述



4 . ChannelPipeline 管道内元素分析 :


① 管道类 : ChannelPipeline 本身的类型是 DefaultChannelPipeline ;

② 管道与通道 : 管道 ChannelPipeline 中可以获取到 Channel 通道 , 通道 Channel 中也可以获取到 管道 ChannelPipeline ;

③ ChannelHandlerContext 双向链表 :

  • 链表头 : head 是 管道处理器上下文 ChannelHandlerContext 的双向链表的链表头 ;

  • 链表尾 : tail 是 管道处理器上下文 ChannelHandlerContext 的双向链表的链表尾 ;

在这里插入图片描述



5 . ChannelHandlerContext 类型 : head 和 tail 都是 ChannelHandlerContext 类型的 ;


① 接口 : ChannelHandlerContext 类型是接口 , 实际使用的是该接口的实现类 ;

public interface ChannelHandlerContext extends AttributeMap, ChannelInboundInvoker, ChannelOutboundInvoker

② 接口实现类 : ChannelHandlerContext 接口有 6 6 6 个实现类 , 常用的是 DefaultChannelHandlerContext 实现类 ;
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值