netty源码解析1

本文深入解析Netty的DefaultChannelPipeline,包括其构造方法和双向链表结构。介绍了AbstractChannelHandlerContext如何处理数据,以及HeadContext和TailContext的作用。此外,还讨论了ByteToMessageDecoder和MessageToByteEncoder的解码与编码过程,以及ChannelFuture和DefaultPromise在处理异步操作中的角色。最后,概述了AbstractNioChannel及其子类的写逻辑。
摘要由CSDN通过智能技术生成

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,那么执行解码操作
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值