【Netty】Netty 核心组件 ( ChannelPipeline 中的 ChannelHandlerContext 双向链表分析 )
文章目录
- 一、 代码示例分析
- 二、 ChannelHandlerContext 双向链表类型
- 三、 Pipeline / ChannelPipeline 管道内双向链表分析
- 四、 数据入站与出站
接上一篇博客 【Netty】Netty 核心组件 ( Pipeline | ChannelPipeline ) 内容 , 在 debug 调试中 , 详细分析 ChannelPipeline 内部的 Handler 双向链表 ;
一、 代码示例分析
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 设置对应的事件 处理器 Handlernew ChannelInitializer<SocketChannel>() {// 创建通道初始化对象@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// 该方法在服务器与客户端连接建立成功后会回调// 获取管道ChannelPipeline pipeline = ch.pipeline();// 为管道加入 HTTP 协议的编解码器 HttpServerCodec,// codec 中的 co 是 coder 编码器的意思, dec 是 decoder 解码器的意思// 第一个字符串是编解码器的名称pipeline.addLast("HttpServerCodec" , new HttpServerCodec());// 为管道 Pipeline 设置处理器 Hanedlerpipeline.addLast("HTTPServerHandler", new HTTPServerHandler());// 管道初始化完成// 在此行代码上打断点 ----------------------------------------------System.out.println("管道初始化完成!");}});// 核心分析代码 ------------------------------------------------------------------------
2 . 元素类型 :
① 头尾元素 : 双向链表的头尾都是自动生成的 , 其类型是 DefaultChannelPipeline , 头尾元素中没有封装 Handler 处理器 ;
② 中间元素 : 双向链表的中间元素是 DefaultChannelHandlerContext 类型的 , 封装了 Handler 处理器 ;
3 . 双向链表元素内封装的 ChannelHandler 类型 : 从头元素之后的第一个元素开始到最后一个元素之间 , 每个双向链表中的元素都封装有一个 ChannelHandler ;
4 . ChannelPipeline 管道中 , 放入了 333 个 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;}@Overridepublic 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 ( 第 000 个元素 ) : 打开 head 元素的成员 , 查看其成员组成 ;
① prev 为空 : 这是双向链表的表头 , 因此其 prev 元素 ( 前一个元素 ) 是空的 ;
② next 元素 : 查看其下一个元素 , 其下一个元素肯定也是 ChannelHandlerContext 类型的 ;
③ 开始表头元素类型 : DefaultChannelPipeline ;
1 . 双向链表第 111 个元素 Handler 类型 : 其 Handler 是 HTTPServer 中的匿名内部类 ChannelInitializer , 也就是创建的 ChannelInitializer 匿名内部类 ;
第 111 个元素 Handler 类型 : ChannelInitializer , 该类继承了 ChannelInboundHandlerAdapter , 因此也是一个处理器 Handler ;
public abstract class ChannelInitializer<C extends Channel> extends ChannelInboundHandlerAdapter
2 . 双向链表第 222 个元素 Handler 类型 : 其 Handler 是 HttpServerCodec 类型的对象, 也就是为 ChannelPipeline 添加的 HttpServerCodec 编解码器 ;
第 222 个元素 Handler 类型 : HttpServerCodec ;
// 获取管道
ChannelPipeline pipeline = ch.pipeline();// 本次示例核心代码 ---------------------------------------------
// 为管道加入 HTTP 协议的编解码器 HttpServerCodec,
// codec 中的 co 是 coder 编码器的意思, dec 是 decoder 解码器的意思
// 第一个字符串是编解码器的名称
pipeline.addLast("HttpServerCodec" , new HttpServerCodec());
// 本次示例核心代码 ---------------------------------------------
3 . 双向链表第 333 个元素 Handler 类型 : 其 Handler 是 HttpServerHandler 类型的对象, 也就是为 ChannelPipeline 添加的 HTTPServerHandler 业务逻辑处理器 ;
① 第 333 个元素 Handler 类型 : HttpServerHandler ;
② HTTPServerHandler 类结构 : 其中 HTTPServerHandler 继承 SimpleChannelInboundHandler<HttpObject> ;
public class HTTPServerHandler extends SimpleChannelInboundHandler\<HttpObject\>
③ 对应的向管道添加 HTTPServerHandler 处理器的代码 :
new ChannelInitializer<SocketChannel>() {// 创建通道初始化对象@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// 该方法在服务器与客户端连接建立成功后会回调// 获取管道ChannelPipeline pipeline = ch.pipeline();// 为管道加入 HTTP 协议的编解码器 HttpServerCodec,// codec 中的 co 是 coder 编码器的意思, dec 是 decoder 解码器的意思// 第一个字符串是编解码器的名称pipeline.addLast("HttpServerCodec" , new HttpServerCodec());// 本次示例核心代码 ---------------------------------------------// 为管道 Pipeline 设置处理器 Hanedlerpipeline.addLast("HTTPServerHandler", new HTTPServerHandler());// 本次示例核心代码 ---------------------------------------------// 管道初始化完成System.out.println("管道初始化完成!");}
}
4 . 双向链表第 444 个元素 : 第四个元素也是双向链表的结尾 , 类型是与链表头元素类型一致 , 是 DefaultChannelPipeline ;
① 第 444 个元素类型 : DefaultChannelPipeline ;
② next 为空 : 其 next 为空 , 说明该元素就是双向链表的结尾 ;
四、 数据入站与出站
1 . 双向链表对应的数据入站与出栈操作 :
① 链表中数据传递 : 在双向链表中 , 将数据按照两个方向进行传递 , 分别是入站和出站操作 ;
② 入站数据 : 从链表的表头 , 传递数据到链表尾部 , 将数据逐个 Handler 传递 , 每个链表元素中的 Handler 对数据都进行对应的处理 ;
③ 出站数据 : 从链表的尾部 , 向表头传递数据 , 经过每个 Handler 都对数据进行相应的处理 ;
以上面的代码示例为例进行解析
2 . 示例中的入站操作 :
① 初始化双向链表 : 客户端请求服务器端资源 , 客户端请求到来后 , 先初始化该 ChannelHandlerContext 双向链表 , 分别放入 ChannelInitializer , HttpServerCodec , HTTPServerHandler 三个 ChannelHandler 通道处理器 ;
② 数据解码 : 客户端请求数据 , 先传入 HttpServerCodec 服务器编解码器中进行处理 , 这里需要将数据解码 ;
③ 业务逻辑 : 然后将 HttpServerCodec 输出的数据 , 输入到用户自定义的 HTTPServerHandler 中进行处理 ;
【Netty】Netty 核心组件 ( ChannelPipeline 中的 ChannelHandlerContext 双向链表分析 )相关推荐
- Netty核心组件 ChannelPipeline和ChannelHandler与ChannelHandler的入站出站规则
概述 Netty中ChannelPipeline与Channel的对应关系是一一对应,也就是每个Channel中有且仅有一个ChannelPipeline,可以通过Channel获取唯一的Channe ...
- Netty 的核心组件
Netty 的核心组件有哪些? 1. Bootstrap 与 ServerBootstrap Bootstrap 与 ServerBootstrap 是 Netty 程序的引导类,主要用于配置各种参数 ...
- Netty的核心组件
Netty是什么? Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序.也就是说,Nett ...
- netty系列之:channelPipeline详解
文章目录 简介 ChannelPipeline 事件传递 DefaultChannelPipeline 总结 简介 我们在介绍channel的时候提到过,几乎channel中所有的实现都是通过chan ...
- Netty学习1——Netty的核心组件
Netty的核心组件 Netty的主要构件块:Channel.回调.Future.事件和ChannelHandler 1.Channel Channel是Java NIO的一个基本构造. 它代表一个到 ...
- Dubbo篇:基于Netty实现Dubbo协议编解码源码分析
Dubbo协议解析 Dubbo协议设计参考了TCP/IP协议,包括协议头和协议体两部分.16字节报文头主要携带了魔法数(0xdabb,用于分割两个不同请求),以及当前请求报文是否是Request.Re ...
- ctf 文件头crc错误_[CTF隐写]png中CRC检验错误的分析
[CTF隐写]png中CRC检验错误的分析 最近接连碰到了3道关于png中CRC检验错误的隐写题,查阅了相关资料后学到了不少姿势,在这里做一个总结 题目来源: bugku-MISC-隐写2 bugku ...
- GPUImage滤镜中的shader代码分析,及自定义滤镜
from: http://blog.csdn.net/vegerjiangsir/article/details/27172143 GPUImage由于使用GPU,顾其在滤镜染色的时候真正使用的是Op ...
- [转]关于形如--error LNK2005: xxx 已经在 msvcrtd.lib ( MSVCR90D.dll ) 中定义--的问题分析解决...
关于形如--error LNK2005: xxx 已经在 msvcrtd.lib ( MSVCR90D.dll ) 中定义--的问题分析解决 转自:http://hi.baidu.com/qinfen ...
最新文章
- hibernate相关收集
- Java :内部类基础详解
- mysql centos7安装_Linux——CentOS7之mysql5.7安装与配置
- linux# 解读wmctrl一览输出的项目
- 关于数据库死锁的检查方法
- Dev C++下载地址和安装教程(图解)
- java json字符串转对象
- VLAN中tagged与untagged的处理
- logistic模型预测人口python_基于python的logistic回归建模预测
- 网络打印机无法接收打印命令
- 找字符串中最长单词C语言,C语言 在已知字符串中找最长单词
- 《内网安全攻防:渗透测试实战指南》读书笔记(八):权限维持分析及防御
- 单片机 数字电压表(TLC2543)
- Redis中的缓存穿透、雪崩、击穿的原因以及解决方案(详解)
- Command ‘pip‘ not found, but can be installed with:
- backpressure 背压介绍
- 06_JavaScript数据结构与算法(六)单向链表
- mysql5.7连接驱动
- KeyBert关键词提取 :原理、方法介绍、代码实践
- 逯遥超实用商务礼仪15讲 帮你如何塑造完美职场形象课程全套(完整版)