一、 代码示例分析
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 ;
1 . 双向链表第 1 11 个元素 Handler 类型 : 其 Handler 是 HTTPServer 中的匿名内部类 ChannelInitializer , 也就是创建的 ChannelInitializer 匿名内部类 ;
第 1 11 个元素 Handler 类型 : ChannelInitializer , 该类继承了 ChannelInboundHandlerAdapter , 因此也是一个处理器 Handler ;
public abstract class ChannelInitializer<C extends Channel> extends ChannelInboundHandlerAdapter
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()); // 本次示例核心代码 ---------------------------------------------