随笔分类
Handler & Pipeline
ChannelHandler
Netty使用不同的事件通知我们状态的改变或者操作的状态
;这使得我们能够基于已经发生的时间来触发适当的动作:
- 记录日志
- 数据转换
- 流的控制
- 应用程序逻辑
Netty是一个网络编程框架,因此事件是按照它们与入站或出站数据流的相关性进行分类的
ChannelHandler用来处理 Channel上的各种事件,分为入站、出站两种;所有的 ChannelHandler连成一串,构成了 Pipeline
ChannelHandler充当了所有处理入站和出站数据的应用程序逻辑的容器
虽然 ChannelInboundHandler和 ChannelOutboundHandler都扩展自 ChannelHandler,但是 Netty能够去区分二者的实现,并且能够确保数据只会在相同定向类型的两个 ChannelHandler之间传递
Netty以适配器的形式提供了大量默认的 ChannelHandler实现
,其旨在简化应用程序处理逻辑的开发过程;ChannelPipeline中的每个 ChannelHandler会去负责将事件转交给链中的下一个 ChannelHandler;这些适配器类 (即它们的子类)将自动执行这个操作,因此在使用时可以只重写那些你想要特殊处理的方法和事件
- 入站处理器通常是
ChannelInboundHandlerAdaptor
的子类,主要用来读取客户端数据,写回结果- 连接已被激活或者连接失活
- 数据读取
- 用户事件
- 错误事件
- 出站处理器通常是
ChannelOutboundHandlerAdaptor
的子类,主要对写出的数据进行加工- 打开或者关闭到远程节点的连接
- 将数据写到或者冲刷到 Socket中
// 这里需要注意一点:对读入数据的处理是从 head开始往后遍历 handler
// 对写出数据的处理是从 tail开始从后往前开始遍历 handler的
如下图:很好地诠释了 handler的执行顺序:区别于入站、出站
流经 ChannelHandler链的入站事件和出站事件:
Netty提供了大量预定义的开箱即用的 ChannelHandler实现,包括用于各种协议 (如 Http 和 SSL / TLS)的 ChannelHandler;在内部,ChannelHandler自己也使用了事件和 Future,使得它们也成为了你的应用程序将使用的相同抽象的消费者
-
针对不同类型的事件调用 ChannelHandler
-
应用程序通过实现或者扩展 ChannelHandler来挂钩到事件的生命周期,并且提供自定义的应用程序逻辑
-
在架构上,ChannelHandler有助于
保持业务逻辑和网络处理代码的分离
这简化了开发过程,因为代码必须不断地演化以来响应不断变化的需求
ChannelPipeline
ChannelPipeline提供了 ChannelHandler链的容器
,并定义了用于在该链上传播入站和出站事件流的 Api
当 Channel被创建时,它会被自动地分配到它专属的 ChannelPipeline
使得事件流经 ChannelPipeline是 ChannelHandler的工作,他们是在应用程序的初始化阶段或者引导阶段被安装的;这些对象接收事件、执行他们内部实现的处理逻辑,并且将数据传递给链中的下一个 ChannelHandler;其执行的顺序是由它们所添加的顺序所决定的
当 ChannelHandler被添加到 ChannelPipeline时,会被分配一个 ChannelHandlerContext
,其代表了 ChannelHandler与 ChannelPipeline之间的绑定;
虽然这个对象可以被用于获取底层的 Channel,但是它主要还是被用于写出站数据
在 Netty中,有两种发送数据的方式;一种,你可以直接写到 Channel中去,这种方式会导致消息从 ChannelPipeline的尾端开始流动;另一种,可以将数据写入到和 ChannelHandler相关联的 ChannelHandlerContext对象中去,这种方式会使得消息从 ChannelPipeline的下一个 ChannelHandler开始流动 (逆序
,context代表的是 ChannelHandler与 ChannelPipeline之间的连接)