文章目录
一、 Pipeline / ChannelPipeline 管道组件
二、 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:11:1 的关系 ;
② 管道与处理器 : 每个 ChannelPipeline 管道中维护了处理器 ChannelHandler 集合 , 管道 ChannelPipeline 与 处理器 Handler 两者是 1 : n 1:n1:n 的关系 ;
③ 处理器与处理器上下文 : 每个 ChannelHandler 处理器都有一个与之对应的 ChannelHandlerContext , 二者是 1 : 1 1:11: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 66 个实现类 , 常用的是 DefaultChannelHandlerContext 实现类 ;