參考Netty API

io.netty.channel.ChannelPipeline

A list of ChannelHandlers which handles or intercepts inbound events and outbount operations of aChannel.ChannelPipeline
implements an advanced form of theIntercepting Filter pattern to give a user full control over how an event is handled and how theChannelHandlers
in a pipeline interact with each other.

Creation of a pipeline

Each channel has its own pipeline and it is created automatically when a new channel is created.

How an event flows in a pipeline

The following diagram describes how I/O events are processed by ChannelHandlers in aChannelPipeline typically. An I/O event is handled
by either aChannelInboundHandler or aChannelOutboundHandler and be forwarded to its closest handler by calling the event propagation methods
defined inChannelHandlerContext, such asChannelHandlerContext.fireChannelRead(Object) andChannelHandlerContext.write(Object).

                                                 I/O Request
via Channel or
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) |
+-------------------------------------------------------------------+

Figure 1

An inbound event is handled by the inbound handlers in the bottom-up direction as shown on the left side of the diagram. An inbound handler usually handles the inbound data generated by the I/O thread on the bottom of the diagram. The inbound data is often
read from a remote peer via the actual input operation such as SocketChannel.read(ByteBuffer). If an inbound event goes beyond the top inbound handler, it is discarded silently, or logged if it needs
your attention.

An outbound event is handled by the outbound handler in the top-down direction as shown on the right side of the diagram. An outbound handler usually generates or transforms the outbound traffic such as write requests. If an outbound event goes beyond the
bottom outbound handler, it is handled by an I/O thread associated with the
Channel
. The I/O thread often performs the actual output operation such asSocketChannel.write(ByteBuffer).

For example, let us assume that we created the following pipeline:

 ChannelPipeline p = ...;
p.addLast("1", new InboundHandlerA());
p.addLast("2", new InboundHandlerB());
p.addLast("3", new OutboundHandlerA());
p.addLast("4", new OutboundHandlerB());
p.addLast("5", new InboundOutboundHandlerX());

In the example above, the class whose name starts with Inbound means it is an inbound handler. The class whose name starts withOutbound means it is a outbound handler.

In the given example configuration, the handler evaluation order is 1, 2, 3, 4, 5 when an event goes inbound. When an event goes outbound, the order is 5, 4, 3, 2, 1. On top of this principle,ChannelPipeline
skips the evaluation of certain handlers to shorten the stack depth:

Forwarding an event to the next handler

As you might noticed in the diagram shows, a handler has to invoke the event propagation methods inChannelHandlerContext to forward an event to its next handler. Those methods include:

and the following example shows how the event propagation is usually done:

 public class MyInboundHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) {
System.out.println("Connected!");
ctx.fireChannelActive();
}
} public clas MyOutboundHandler extends ChannelOutboundHandlerAdapter {
@Override
public void close(ChannelHandlerContext ctx, ChannelPromise promise) {
System.out.println("Closing ..");
ctx.close(promise);
}
}

Building a pipeline

A user is supposed to have one or more ChannelHandlers in a pipeline to receive I/O events (e.g. read) and to request I/O operations (e.g. write and close). For example, a typical server will have
the following handlers in each channel's pipeline, but your mileage may vary depending on the complexity and characteristics of the protocol and business logic:

  1. Protocol Decoder - translates binary data (e.g. ByteBuf) into a Java object.
  2. Protocol Encoder - translates a Java object into binary data.
  3. Business Logic Handler - performs the actual business logic (e.g. database access).

and it could be represented as shown in the following example:

 static final EventExecutorGroup group = new DefaultEventExecutorGroup(16);
... ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("decoder", new MyProtocolDecoder());
pipeline.addLast("encoder", new MyProtocolEncoder()); // Tell the pipeline to run MyBusinessLogicHandler's event handler methods
// in a different thread than an I/O thread so that the I/O thread is not blocked by
// a time-consuming task.
// If your business logic is fully asynchronous or finished very quickly, you don't
// need to specify a group.
pipeline.addLast(group, "handler", new MyBusinessLogicHandler());

Thread safety

A ChannelHandler can be added or removed at any time because aChannelPipeline is thread safe. For example, you can insert an encryption
handler when sensitive information is about to be exchanged, and remove it after the exchange.

—————>>>>>>>>>>>>>>>>>>华丽的分界线<<<<<<<<<<<<<<<<<—————————————

Figure1 变形:

  +-------------------------------------------------------------------+
| IN |
| | |
| | |
| [(Socket)read] |
| | |
| | |
| \|/ |
| +----------+----------+ |
| | Inbound Handler 1 | |
| +----------+----------+ |
| | |
| \|/ |
| +----------+----------+ |
| | Inbound Handler 2 | |
| +----------+----------+ |
| . |
| . |
| \./ |
| ChannelHandlerContext.FireIN_EVT |
| [ method call] |
| . |
| . |
| \./ |
| +----------+----------+ |
| | Inbound Handler N-1 | |
| +----------+----------+ |
| \|/ |
| | |
| +----------+----------+ |
| | Inbound Handler N | |
| +----------+----------+ |
| | |
| \|/ |
| | |
+---------------------------------+---------------------------------+
| | |
| | |
| Application |
| | |
| | |
+---------------------------------+---------------------------------+
| | |
| \|/ |
| +-----------+----------+ |
| | Outbound Handler 1 | |
| +-----------+----------+ |
| | |
| \|/
| +-----------+----------+ |
| | Outbound Handler 2 | |
| +-----------+----------+ |
| . |
| . |
| \./ |
| ChannelHandlerContext.OUT_EVT() |
| [ method call] |
| . |
| . |
| \./ |
| +-----------+----------+ |
| | Outbound Handler M-1 | |
| +-----------+----------+ |
| | |
| \|/ |
| +-----------+----------+ |
| | Outbound Handler M | |
| +-----------+----------+ |
| | |
| \|/ |
| [(Socket)write] |
| | |
| | |
| \|/ |
| | |
| OUT |
+---------------+-----------------------------------+---------------+

责任链模式:

在阎宏博士的《JAVA与模式》一书中开头是这样描写叙述责任链(Chain of Responsibility)模式的:

  责任链模式是一种对象的行为模式。在责任链模式里,非常多对象由每个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的client并不知道链上的哪一个对象终于处理这个请求,这使得系统能够在不影响client的情况下动态地又一次组织和分配责任。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd29ya2luZ19icmFpbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

责任链模式涉及到的角色例如以下所看到的:

  ●  抽象处理者(Handler)角色:定义出一个处理请求的接口。假设须要,接口能够定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。

上图中Handler类的聚合关系给出了详细子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。

  ●  详细处理者(ConcreteHandler)角色:详细处理者接到请求后。能够选择将请求处理掉,或者将请求传给下家。

因为详细处理者持有对下家的引用,因此,假设须要,详细处理者能够訪问下家。

Java website development中的filter也是责任链模式。

參考文章:http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html。

Netty源代码学习——ChannelPipeline模型分析的更多相关文章

  1. Netty源代码学习——EventLoopGroup原理:NioEventLoopGroup分析

    类结构图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd29ya2luZ19icmFpbg==/font/5a6L5L2T/fontsize/400/f ...

  2. Netty源代码学习——Included transports(变速箱)

    Transport API核心: Channel介面 类图表示Channel含有Pipeline和Config接口,pipeline上一节有所介绍. Channel是线程安全的,这表示在多线环境下操作 ...

  3. Netty 源码学习——客户端流程分析

    Netty 源码学习--客户端流程分析 友情提醒: 需要观看者具备一些 NIO 的知识,否则看起来有的地方可能会不明白. 使用版本依赖 <dependency> <groupId&g ...

  4. Netty中的ChannelPipeline源码分析

    ChannelPipeline在Netty中是用来处理请求的责任链,默认实现是DefaultChannelPipeline,其构造方法如下: private final Channel channel ...

  5. ROS_Kinetic_29 kamtoa simulation学习与示例分析(一)

    致谢源代码网址:https://github.com/Tutorgaming/kamtoa-simulation kamtoa simulation学习与示例分析(一) 源码学习与分析是学习ROS,包 ...

  6. 《精通并发与Netty》学习笔记(01 - netty介绍及环境搭建)

    一.Netty介绍     Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序.     ...

  7. struts2源代码学习之初始化(一)

    看struts2源代码已有一段时日,从今天開始,就做一个总结吧. 首先,先看看怎么调试struts2源代码吧,主要是下面步骤: 使用Myeclipse创建一个webproject 导入struts2须 ...

  8. 读Flask源代码学习Python--config原理

    读Flask源代码学习Python--config原理 个人学习笔记,水平有限.如果理解错误的地方,请大家指出来,谢谢!第一次写文章,发现好累--!. 起因   莫名其妙在第一份工作中使用了从来没有接 ...

  9. dlib人脸关键点检测的模型分析与压缩

    本文系原创,转载请注明出处~ 小喵的博客:https://www.miaoerduo.com 博客原文(排版更精美):https://www.miaoerduo.com/c/dlib人脸关键点检测的模 ...

随机推荐

  1. BZOJ 1018

    program bzoj1018; type node=..] of boolean; pair=..] of boolean; var tot,c,i,j,k,x1,y1,x2,y2:longint ...

  2. poj 2245 Lotto(dfs)

    题目链接:http://poj.org/problem?id=2245 思路分析:无重复元素组合组合问题,使用暴力枚举法,注意剪枝条件. 代码如下: #include <iostream> ...

  3. jQuery报错:Uncaught ReferenceError: $ is not defined

    在使用jQuery的时候,发现有如下报错: Uncaught ReferenceError: $ is not defined  (anonymous function) 出现这个报错的原因: 1.j ...

  4. 周根项《一分钟速算》全集播放&amp;下载地址

    点击图片就可以观看 ↓↓↓↓↓↓↓↓ 第1章:指算法 周根项<一分钟速算>第1章:指算法 第一节 对手的认识 周根项<一分钟速算>第1章:指算法 第二节 个位数比十位数大1乘以 ...

  5. for语句之打印三角形问题

    1.左下角直角三角形 Console.Write("请输入要打印几行:"); int a = Convert.ToInt32(Console.ReadLine()); ; i &l ...

  6. 【Eclipse】Tomcat 改变发布路径

    关闭服务,删除里面的所有项目,clean,然后双击服务,发布路径修改就可以点击了.当重新发布了项目后,发布路径修改的按钮又会恢复不可点击状态.

  7. ubuntu安装ulipad

    以下内容部分我是从其他地方找的,并且做了适当的修改,亲身测试可以安装成功   在安装ulipad之前,先安装一个超级好用的Python的交互式Shell--iPython.iPython功能很强大, ...

  8. POJ 1458 最长公共子序列 LCS

    经典的最长公共子序列问题. 状态转移方程为 : if(x[i] == Y[j]) dp[i, j] = dp[i - 1, j - 1] +1 else dp[i, j] = max(dp[i - 1 ...

  9. bresenham算法的FPGA的实现2

    在上一篇里http://www.cnblogs.com/sepeng/p/4045593.html <bresenham算法的FPGA的实现1>已经做了一个整体框架的布局,但是那个程序只是 ...

  10. 有什么很好的软件是用 Qt 编写的?

    作者:尘中远链接:http://www.zhihu.com/question/19630324/answer/19365369来源:知乎 一些出名的例子如下:(wiki搬运) 3DSlicer, a ...