ChannelPipeline
Just look at the name can knowChannel
the pipeline. This article deals combined with its default implementation classDefaultChannelPipeline
to make it a simple introduction.
sample graph
The figure is provided by the official ChannelPipeline
case diagram. IO requests over ChannelOutboundHandler
the ChannelOutboundHandler
write to the server after treatment, after receiving the service read by ChannelInboundHandler
the processing sequence.
Look at the following DefaultChannelPipeline
class diagram:
DefaultChannelPipeline
implements ChannelPipeline
an interface, and ChannelPipeline
has inherited ChannelInboundInvoker
, ChannelOutboundInvoker
and Iterable
.
ChannelInboundInvoker
: Launch of ChannelPipeline
a next ChannelInboundHandler
call method.
ChannelOutboundInvoker
: Launch of ChannelPipeline
a next ChannelOutboundHandler
call method.
Iterable
: It can be traversed ChannelPipeline
in ChannelHandler
.
NioEventLoop
Inherited from SingleThreadEventLoop
, but SingleThreadEventLoop
also inherited from SingleThreadEventExecutor
.
SingleThreadEventExecutor
Internal holds a Thread object is the Netty
basis for multi-threaded.
It is believed that one NioEventLoop
is bound to a specific thread, and during its life cycle, binding thread will not change.
DefaultChannelPipeline
DefaultChannelPipeline
The main job is to ChannelHandler
manage, including ChannelHandler
the increase or decrease, triggering events and so on.
ChannelHandler
Increase or decrease
In a addFirst
method as an example:
public final ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler) {
final AbstractChannelHandlerContext newCtx;
synchronized (this) {
// 检查handler是否可以共享
checkMultiplicity(handler);
// 给AbstractChannelHandlerContext起个独立的名字
name = filterName(name, handler);
// 创建DefaultChannelHandlerContext
newCtx = newContext(group, name, handler);
// 执行实际的添加操作
addFirst0(newCtx);
// channel尚未注册到eventloop
if (!registered) {
// 设置newCtx的状态为ADD_PENDING
newCtx.setAddPending();
// 设置过一会回调ChannelHandler的handlerAdded方法
callHandlerCallbackLater(newCtx, true);
return this;
}
EventExecutor executor = newCtx.executor();
if (!executor.inEventLoop()) {
newCtx.setAddPending();
executor.execute(new Runnable() {
@Override
public void run() {
callHandlerAdded0(newCtx);
}
});
return this;
}
}
callHandlerAdded0(newCtx);
return this;
}
addFirst
方法先检查添加的ChannelHandler
是否可以共享(判断共享的方法是对于每个channel当前ChannelHandler是否需要不同的状态),再创建ChannelHandler
的上下文关系,使ChannelHandler
以链表方式存在于ChannelPipeline
中。当ChannelHandler
添加成功后,再调用ChannelHandler
的handlerAdded
方法。其它的添加方式和addFirst
类似。
事件触发
以fireChannelActive
方法为例:
public final ChannelPipeline fireChannelActive() {
AbstractChannelHandlerContext.invokeChannelActive(head);
return this;
}
从HeadContext
的head开始,依次触发下一个ChannelHandler
的channelActive
方法。
本篇简单介绍了ChannelPipeline
的相关概念,当ChannelHandler
介绍完后,再具体介绍ChannelPipeline
中的HeadContext
和TailContext
。
文中帖的代码注释全在:KAMIJYOUDOUMA, 有兴趣的童鞋可以关注一下。
本篇到此结束,如果读完觉得有收获的话,欢迎点赞、关注、加公众号【贰级天災】,查阅更多精彩历史!!!