文章目录
DefaultChannelPipeline
implements ChannelPipeline
- 构造方法,维护头尾节点,头尾节点组成双向链表。ChannelHandler封装成ChannelHandlerContext,再有ChannelHandlerContext组成链表的元素。
protected DefaultChannelPipeline(Channel channel) {
// ...
// 头尾节点
tail = new TailContext(this);
head = new HeadContext(this);
// 双向链表
head.next = tail;
tail.prev = head;
}
- 往尾部添加handler,头尾节点固定,新增的handler的下一个节点为尾节点
private void addLast0(AbstractChannelHandlerContext newCtx) {
// 在链表添加一个handler,即在head和tail之间构建双向链表
AbstractChannelHandlerContext prev = tail.prev;
newCtx.prev = prev;
newCtx.next = tail;
prev.next = newCtx;
tail.prev = newCtx;
}
- 写操作,很明显,从尾节点开始往前面的节点写数据
public final ChannelFuture write(Object msg) {
return tail.write(msg);
}
AbstractChannelHandlerContext
implements ChannelHandlerContext
- 向通道写数据
static void invokeChannelRead(final AbstractChannelHandlerContext next, Object msg) {
final Object m = next.pipeline.touch(ObjectUtil.checkNotNull(msg, "msg"), next);
EventExecutor executor = next.executor();
if (executor.inEventLoop()) {
// 如果是同一个线程,那么执行下一个节点的invokeChannelRead方法
next.invokeChannelRead(m);
} else {
// 如果不是同一线程,那么投放到队列去执行
executor.execute(new Runnable() {
@Override
public void run() {
next.invokeChannelRead(m);
}
});
}
}
- 找到下一个InboundHandler(从head到tail的顺序找)
private AbstractChannelHandlerContext findContextInbound() {
AbstractChannelHandlerContext ctx = this;
do {
ctx = ctx.next;
} while (!ctx.inbound);
return ctx;
}
- 找到下一个OutboundHandler(从tail到head的顺序)
private AbstractChannelHandlerContext findContextOutbound() {
AbstractChannelHandlerContext ctx = this;
do {
ctx = ctx.prev;
} while (!ctx.outbound);
return ctx;
}
HeadContext
extends AbstractChannelHandlerContext implements ChannelOutboundHandler, ChannelInboundHandler,它是一个context,同时是一个出入站handler,说明不管出入站,都会流经。
- HeadContext是入站的第一个handler,负责传递入站消息到下一个ChannelInboundHandler
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelInactive();
}
- HeadContext是出站的最后一个handler,直接往网络发送
@Override
public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
unsafe.close(promise);
}
@Override
public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
unsafe.deregister(promise);
}
TailContext
extends AbstractChannelHandlerContext implements ChannelInboundHandler,它是一个context,同时是一个入站handler,也是最后一个入站handler
- TailContext可用来做资源的释放,假如前面的handler不释放资源,那么它必须把释放资源的操作交给后面的handler,最后由TailContext处理
protected void onUnhandledInboundMessage(Object msg) {
try {
logger.debug(
"Discarded inbound message {} that reached at the tail of the pipeline. " +
"Please check your pipeline configuration.", msg);
} finally {
ReferenceCountUtil.release(msg);
}
}
ByteToMessageDecoder
extends ChannelInboundHandlerAdapter
- 读操作
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof ByteBuf) {
// 如果消息是一个ByteBuf,那么执行解码操作