Channel.write() 和 ChannelHandlerContext.write() 的区别

看了下netty 源代码, 终于明白了
Channel.write() 和 ChannelHandlerContext.write() 的区别了
网上说的都不是很清楚 


首先注明我的netty版本
<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty-all</artifactId>
	<version>4.0.36.Final</version>
</dependency>



ChannelPipeline处理ChannelHandler的顺序:


pipeline中的handler 处理的请求分为两类: 读 和 写
对于读请求 : 从handler链表的 head  到  tail     挨个的处理, 跳过 ChannelOutboundHandler
对于写请求 : 从handler链表的 tail      到  head 挨个的处理, 跳过 ChannelInboundHandler


1 调用  Channel.write(), 会直接调用ChannelPipeline.write()
    @Override
    public ChannelFuture write(Object msg) {
        return pipeline.write(msg);
    }

    @Override
    public ChannelFuture write(Object msg, ChannelPromise promise) {
        return pipeline.write(msg, promise);
    }

    @Override
    public ChannelFuture writeAndFlush(Object msg) {
        return pipeline.writeAndFlush(msg);
    }

    @Override
    public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {
        return pipeline.writeAndFlush(msg, promise);
    }

ChannelPipeline .write() 直接调用 tail指向的 最后一个handler的 write
    @Override
    public ChannelFuture write(Object msg) {
        return tail.write(msg);
    }

    @Override
    public ChannelFuture write(Object msg, ChannelPromise promise) {
        return tail.write(msg, promise);
    }
可以看到 调用的是ctx.prev获取前一个, 所以写从tail到head


2 调用ChannelHandlerContext.write() 
首先通过findContextOutbound找到当前ChannelHandlerContext的上一个OutboundContext
再调用它执行具体的写入逻辑
    private void write(Object msg, boolean flush, ChannelPromise promise) {
        AbstractChannelHandlerContext next = findContextOutbound();
        EventExecutor executor = next.executor();
        if (executor.inEventLoop()) {
            next.invokeWrite(msg, promise);
            if (flush) {
                next.invokeFlush();
            }
        } else {
            AbstractWriteTask task;
            if (flush) {
                task = WriteAndFlushTask.newInstance(next, msg, promise);
            }  else {
                task = WriteTask.newInstance(next, msg, promise);
            }
            safeExecute(executor, task, promise, msg);
        }
    }

    private AbstractChannelHandlerContext findContextOutbound() {
        AbstractChannelHandlerContext ctx = this;
        do {
            ctx = ctx.prev;
        } while (!ctx.outbound);
        return ctx;
    }


结论:
Channel.write()  :                        从 tail 到 head 调用每一个outbound 的  ChannelHandlerContext.write
ChannelHandlerContext.write() : 从当前的Context, 找到上一个outbound, 从后向前调用 write


  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值