文章目录
1、netty的工作流程
- ChannelPipeline接口:每一个Channel通道都会有一个ChannelPipeline,责任链的核心组件,同时也是HandlerContext的管理容器(链表的形式管理),事件在各个ChannelHandlerContext中传递。我们可以把他理解为管道,netty的读、写、连接等事件在该通道"流动"。
- ChannelHandlerContext接口:ChannelHandler的上下文环境,所以其封装一个具体的ChannelHandler,同时为ChannelHandler运行提供一个线程环境ChannelHandlerInvoker对象。
- ChannelHandlerInvoker接口:ChannelHandler的运行的线程环境所有其持有一个EventExecutor(netty的线程调度对象)。
- ChannelHandler接口:真正对读、写等IO事件进行处理的对象,它可以选择性地拦截和处理自己感兴趣地事件,也可以透传和终止事件。IO处理事件不同业务处理模式不同,所以这里是netty暴露给业务代码的扩展点,一般来说使用netty主要是通过实现自定义的ChannelHandler。
- ChannelHandlerAdapter:ChannelHandler有很多接口方法,但是我们自定义实现的时候可能只关心自己感兴趣的事件,不必实现ChannelHandler的所有接口,Netty提供了ChannelHandlerAdapter基类它以透传事件的形式实现了所有接口,如果用户关心某个事件,只需要覆盖ChannelHandlerAdapter对应的方法即可。
2、ChannelPipeline接口介绍
2.1、相关概述
ChannelPipeline接口的默认实现为DefaultChannelPipeline,该类主要作用如下:
- 管理所有的ChannelHandlerContext对象,它是以双向列表的形式管理ChannelHandlerContext,其中提供了两个默认的头(head)尾(tail)ChannelHandlerContext对象,其中该类有大量的方法来添加(addXxx)、获取(getXxx)、移除(removeXxx) ChannelHandlerContext的方法
- 持有ChannelHandlerContext的线程运行环境ChannelHandlerInvoker ,他根据ChannelPipeline传入的EventExecutorGroup中的线程池对象创建对应的invoker 存放到Map<EventExecutorGroup, ChannelHandlerInvoker> childInvokers中。
- ChannelHandlerContext对象还通过名字作为key存放到map集合name2ctx中。
2.2、核心方法
主要方法 | 描述 |
---|---|
addXxx/rmove/replace/get/last/first | 管理链表ChannelHandlerContext对象(增、删、改、查) |
fireXxx | 触发其持有的Handler对应的方法比如fireChannelActive方法最终触发handler的channelActive(当前channel激活的时候触发) |
bind/connect/disconnect/close/flush/read/write | 此类方法是其进行网络IO操作的功能方法 比如服务端绑定、客户端连接、关闭、读写事件。 |
2.2.1、addXxx/rmove/replace/get/last/first
这类方法主要是进行ChannelHandlerContext对象的增删查改,逻辑很相似所以这里只分析一个addLast方法,其他的请同学自行分析。addLast有两个重载方法区别是
@Override
public ChannelPipeline addLast(String name, ChannelHandler handler) {
return addLast((ChannelHandlerInvoker) null, name, handler);
}
//包含EventExecutorGroup 有则会调用findInvoker为其线程创建一个DefaultChannelHandlerInvoker 如果没有group 则不创建
@Override
public ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
return addLast(findInvoker(group), name, handler);
}
//添加多个handler
@Override
public ChannelPipeline addLast(EventExecutorGroup group,ChannelHandler ....handler) {
//循环遍历添加 并调用generateName方法为handler生产明细
addLast(invoker, generateName(h), h);
}
最终调用如下方法
public ChannelPipeline addLast(ChannelHandlerInvoker invoker, final String name, ChannelHandler handler) {
synchronized (this) {
//检查名字是否重复 从name2ctx判断是否存在
checkDuplicateName(name);
//Handler 包装成HandlerContext
DefaultChannelHandlerContext newCtx =
new DefaultChannelHandlerContext(this, invoker, name, handler);
//执行具体的链表添加操作
addLast0(name, newCtx);
}
return this;
}
addLast0()方法具体链表添加操作
private void addLast0