Netty ChannelPipeline

Netty 使用ChannelPipeline来实现拦截链路调用

 

*                                                 I/O Request
* via {@link Channel} or
* {@link ChannelHandlerContext}
* |
* +---------------------------------------------------+---------------+
* | ChannelPipeline | |
* | \|/ |
* | +---------------------+ +-----------+----------+ |
* | | Inbound Handler N | | Outbound Handler 1 | |
* | +----------+----------+ +-----------+----------+ |
* | /|\ | |
* | | \|/ |
* | +----------+----------+ +-----------+----------+ |
* | | Inbound Handler N-1 | | Outbound Handler 2 | |
* | +----------+----------+ +-----------+----------+ |
* | /|\ . |
* | . . |
* | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
* | [ method call] [method call] |
* | . . |
* | . \|/ |
* | +----------+----------+ +-----------+----------+ |
* | | Inbound Handler 2 | | Outbound Handler M-1 | |
* | +----------+----------+ +-----------+----------+ |
* | /|\ | |
* | | \|/ |
* | +----------+----------+ +-----------+----------+ |
* | | Inbound Handler 1 | | Outbound Handler M | |
* | +----------+----------+ +-----------+----------+ |
* | /|\ | |
* +---------------+-----------------------------------+---------------+
* | \|/
* +---------------+-----------------------------------+---------------+
* | | | |
* | [ Socket.read() ] [ Socket.write() ] |
* | |
* | Netty Internal I/O Threads (Transport Implementation) |
* +-------------------------------------------------------------------+

例如 fireChannelRead为例
1.1 AbstractChannelHandlerContext#fireChannelRead
1 @Override
2     public ChannelHandlerContext fireChannelRead(final Object msg) {
      //findContextInbound方法负责寻找next Context
3 invokeChannelRead(findContextInbound(), msg); 4 return this; 5 }

  1.2  AbstractChannelHandlerContext#invokeChannelRead(io.netty.channel.AbstractChannelHandlerContext, java.lang.Object)

 1     static void invokeChannelRead(final AbstractChannelHandlerContext next, final Object msg) {
 2         ObjectUtil.checkNotNull(msg, "msg");
 3         EventExecutor executor = next.executor();
 4         if (executor.inEventLoop()) {
 5             next.invokeChannelRead(msg);
 6         } else {
 7             executor.execute(new Runnable() {
 8                 @Override
 9                 public void run() {
10                     next.invokeChannelRead(msg);
11                 }
12             });
13         }
14     }

 1.3 AbstractChannelHandlerContext#invokeChannelRead(java.lang.Object)

 1     private void invokeChannelRead(Object msg) {
 2         if (invokeHandler()) {
 3             try {//Context中handler实际处理逻辑
 4                 ((ChannelInboundHandler) handler()).channelRead(this, msg);
 5             } catch (Throwable t) {
 6                 notifyHandlerException(t);
 7             }
 8         } else {
 9             fireChannelRead(msg);
10         }
11     }

1.4 以LoggingHandler为例  io.netty.handler.logging.LoggingHandler#channelRead

1     @Override
2     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
      //这一行代码 是LoggerHandler的实际处理逻辑
3 logMessage(ctx, "RECEIVED", msg);
      //这一行代码是链路调用的关键,调用1.1,形成链路调用
4 ctx.fireChannelRead(msg); 5 }

 

 

参考 https://blog.csdn.net/zxhoo/article/details/17264263

posted on 2018-12-03 16:38  持续在更新  阅读(191)  评论(0编辑  收藏  举报

导航