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

版权声明:本文为博主原创文章,未经博主允许不得转载。

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

 

 

首先注明我的netty版本

```

  1. <span style="font-size:14px;"><dependency>  
  2.     <groupId>io.netty</groupId>  
  3.     <artifactId>netty-all</artifactId>  
  4.     <version>4.0.36.Final</version>  
  5. </dependency></span> 
  6. ```


 

 

ChannelPipeline处理ChannelHandler的顺序:

 

pipeline中的handler 处理的请求分为两类: 读 和 写

对于读请求 : 从handler链表的 head  到  tail     挨个的处理, 跳过 ChannelOutboundHandler

对于写请求 : 从handler链表的 tail      到  head 挨个的处理, 跳过 ChannelInboundHandler

 

 

1 调用 Channel.write(), 会直接调用ChannelPipeline.write()

[java] view plain copy

  1. @Override  
  2. public ChannelFuture write(Object msg) {  
  3.     return pipeline.write(msg);  
  4. }  
  5.   
  6. @Override  
  7. public ChannelFuture write(Object msg, ChannelPromise promise) {  
  8.     return pipeline.write(msg, promise);  
  9. }  
  10.   
  11. @Override  
  12. public ChannelFuture writeAndFlush(Object msg) {  
  13.     return pipeline.writeAndFlush(msg);  
  14. }  
  15.   
  16. @Override  
  17. public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {  
  18.     return pipeline.writeAndFlush(msg, promise);  
  19. }  


而ChannelPipeline.write() 直接调用 tail指向的 最后一个handler的 write[java] view plain copy

  1. @Override  
  2. public ChannelFuture write(Object msg) {  
  3.     return tail.write(msg);  
  4. }  
  5.   
  6. @Override  
  7. public ChannelFuture write(Object msg, ChannelPromise promise) {  
  8.     return tail.write(msg, promise);  
  9. }  

可以看到 调用的是ctx.prev获取前一个, 所以写从tail到head
 

 

2 调用ChannelHandlerContext.write() 

首先通过findContextOutbound找到当前ChannelHandlerContext的上一个OutboundContext

再调用它执行具体的写入逻辑

[java] view plain copy

  1. private void write(Object msg, boolean flush, ChannelPromise promise) {  
  2.     AbstractChannelHandlerContext next = findContextOutbound();  
  3.     EventExecutor executor = next.executor();  
  4.     if (executor.inEventLoop()) {  
  5.         next.invokeWrite(msg, promise);  
  6.         if (flush) {  
  7.             next.invokeFlush();  
  8.         }  
  9.     } else {  
  10.         AbstractWriteTask task;  
  11.         if (flush) {  
  12.             task = WriteAndFlushTask.newInstance(next, msg, promise);  
  13.         }  else {  
  14.             task = WriteTask.newInstance(next, msg, promise);  
  15.         }  
  16.         safeExecute(executor, task, promise, msg);  
  17.     }  
  18. }  


[java] view plain copy

  1. private AbstractChannelHandlerContext findContextOutbound() {  
  2.     AbstractChannelHandlerContext ctx = this;  
  3.     do {  
  4.         ctx = ctx.prev;  
  5.     } while (!ctx.outbound);  
  6.     return ctx;  
  7. }  

 

 

结论:

Channel.write()  :                        从 tail 到 head 调用每一个outbound 的 ChannelHandlerContext.write

ChannelHandlerContext.write() : 从当前的Context, 找到上一个outbound, 从后向前调用 write

转载于:https://my.oschina.net/u/199488/blog/877642

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值