Netty的ChannelPipeline
来源:互联网 发布:java与php的区别 编辑:程序博客网 时间:2024/06/05 14:58
1、如何理解Netty的ChannelPipeline
在Netty中,每个Channel被创建的时候都需要被关联一个对应的pipeline(通道),这种关联关系是永久的(整个程序运行的生命周期中)。ChannelPipeline可以理解成一个消息( 或消息事件,ChanelEvent)流转的通道,在这个通道中可以被附上许多用来处理消息的handler,当消息在这个通道中流转的时候,如果有与这个消息类型相对应的handler,就会触发这个handler去执行相应的动作。它实现了Intercepting Filter模式(个人理解与Filter Chain模式类似)。
可以通过下面这句话来理解一些相关的概念:ChannelEvents are processed by ChannelHandlers in a ChannelPipeline
2、ChannelPipeline的创建方式
Netty的作者建议采用辅助类org.jboss.netty.channel.Channels的静态无参函数pipeline来创建一个ChannelPipeline对象,从源代码上看其实就是调用了DefaultChannelPipeline的无参构造函数,返回new出来的对象而已。
3、消息的流转
Netty中消息的流转有两个方向:上行、下行
因此,处理消息事件(ChannelEvent)的处理器(ChannelHandler)大致可以分为两个方向:ChannelUpstreamHandler、ChannelDownstreamHandler
* I/O Request
* via {@link Channel} or
* {@link ChannelHandlerContext}
* |
* +----------------------------------------+--------------- +
* | ChannelPipeline | |
* | \|/ |
* | + ----------------------+ +----------- +------------+ |
* | | Upstream Handler N | | Downstream Handler 1 | |
* | + ----------+----------- + +-----------+ ------------+ |
* | /|\ | |
* | | \|/ |
* | + ----------+----------- + +-----------+ ------------+ |
* | | Upstream Handler N -1 | | Downstream Handler 2 | |
* | + ----------+----------- + +-----------+ ------------+ |
* | /|\ . |
* | . . |
* | [ sendUpstream() ] [ sendDownstream() ] |
* | [ + INBOUND data ] [ + OUTBOUND data ] |
* | . . |
* | . \|/ |
* | + ----------+----------- + +-----------+ ------------+ |
* | | Upstream Handler 2 | | Downstream Handler M -1 | |
* | + ----------+----------- + +-----------+ ------------+ |
* | /|\ | |
* | | \|/ |
* | + ----------+----------- + +-----------+ ------------+ |
* | | Upstream Handler 1 | | Downstream Handler M | |
* | + ----------+----------- + +-----------+ ------------+ |
* | /|\ | |
* +-------------+ --------------------------+--------------- +
* | \|/
* +-------------+ --------------------------+--------------- +
* | | | |
* | [ Socket.read() ] [ Socket.write() ] |
* | |
* | Netty Internal I/O Threads (Transport Implementation) |
* +--------------------------------------------------------+
以upstream为例,从socket读出来的数据,逐渐往上进行传递,即原始数据依次往上被进行解析,可能因为所需要的业务数据外面包裹着许多其它附加的数据。如加密、验证、签名等。
downstream与此相反,即把业务数据进行一层层地加密、签名等处理后,写到socket中发出去。这个模型其实可以参考(TCP的七层模型)
4 、pipeline中的handlers顺序如何理解
在添加handler的时候,如果理解顺序。可以把pipeline理解成一个队列,addLast是添加到队列的尾部,addFirst是添加到队列的头部。
upstream的方向是从头到尾,downstream的方向是从尾到头。
5、 多线程环境
ChannelPipeline中的handler是可以在任何时候动态地增加或者删除的,因为ChannelPipeline本身是线程安全的(这点由Netty本身去保证)
6、 ChannelPipeline实例具体解析
在对ChannelPipeline进行解析时,以Netty提供的一个默认实现DefaultChannelPipeline来进行解析,先来看下这个类的一些成员变量(去除日志相关成员logger)
static final ChannelSink discardingSink = new DiscardingChannelSink();
private volatile Channel channel;
private volatile ChannelSink sink;
private volatile DefaultChannelHandlerContext head;
private volatile DefaultChannelHandlerContext tail;
private final Map<String, DefaultChannelHandlerContext> name2ctx =
new HashMap<String, DefaultChannelHandlerContext>(4);
discardingSink是用来处理上行到最上,或者下行到最下时的对消息事件的处理,这个可以不用太关注
主要来关注下head、tail、name2ctx,head和tail这一看就是链表的头和尾,可以进一步猜想pipeline中的handlers是按照一个链表排列的。name2ctx用一个map结构提供名称到handler的映射关系(通过handlerContext可以找到相应的handler)。
下面以addLast为例来进行解析
public synchronized void addLast(String name, ChannelHandler handler) {
if (name2ctx.isEmpty()) {
init(name, handler);
} else {
checkDuplicateName(name);
DefaultChannelHandlerContext oldTail = tail;
DefaultChannelHandlerContext newTail = new DefaultChannelHandlerContext(oldTail, null, name, handler);
callBeforeAdd(newTail);
oldTail.next = newTail;
tail = newTail;
name2ctx.put(name, newTail);
callAfterAdd(newTail);
}
}
依赖DefaultChannelHandlerContext来实现队列结构,在DefaultChannelHandlerContext中有指向前一个和后一个的引用,就不细看,只用看一个DefaultChannelHandlerContext的成员变量即可。
private final class DefaultChannelHandlerContext implements ChannelHandlerContext {
volatile DefaultChannelHandlerContext next;
volatile DefaultChannelHandlerContext prev;
private final String name;
private final ChannelHandler handler;
private final boolean canHandleUpstream;
private final boolean canHandleDownstream;
private volatile Object attachment;
0 0
- Netty的ChannelPipeline
- Netty:ChannelPipeline
- java netty之ChannelPipeline
- 03 netty channelPipeline
- netty-channel-channelPipeline
- Netty教程-ChannelPipeline
- Netty源码分析:ChannelPipeline
- netty源码分析之ChannelPipeline
- netty源码分析之ChannelPipeline
- Netty 之 ChannelHandler,ChannelHandlerContext,ChannelPipeline
- 【Netty源码】ChannelPipeline源码剖析
- Netty源码分析之二【贯穿Netty的大动脉──ChannelPipeline】
- netty源码分析(十)ChannelPipeline创建时机与高级拦截过滤器模式的运用
- netty ChannelPipeline流处理源码详细分析
- Netty ChannelPipeline 中的addFirst和addLast实现
- 【Netty源码学习】ChannelPipeline(一)
- netty源码分析 之四 transport(ChannelPipeline)
- [netty源码分析]--ChannelPipeline源码分析(一)
- Netty的ChannelFuture
- Oracle中INSTR和SUBSTR的用法
- dddddddddddddddd
- 广告精准投放笔记
- matlab求导数
- Netty的ChannelPipeline
- WIN7 开启远程连接以及远程桌面连接
- c3p0,dbcp和proxool比较
- ios绘图
- Java面试题(1)
- Ajax的工作原理
- TabWidget
- linux 添加新硬盘方法
- 天弘借余额宝变老大 华夏欲借微信翻盘