Netty学习----ChannelHandler和Channe

2019-01-17  本文已影响0人  何何与呵呵呵
ChannelHandler家族

ChannelUnregistered Channel 已经被创建,但还未注册到EventLoop
ChannelRegistered Channel 已经被注册到了EventLoop
ChannelActive Channel 处于活动状态(已经连接到它的远程节点)。它现在可以接收和发送数据了
ChannelInactive Channel 没有连接到远程节点


Channel 的状态模型

handlerAdded 当把ChannelHandler 添加到ChannelPipeline 中时被调用
handlerRemoved 当从ChannelPipeline 中移除ChannelHandler 时被调用
exceptionCaught 当处理过程中在ChannelPipeline 中有错误产生时被调用

channelRegistered 当Channel 已经注册到它的EventLoop 并且能够处理I/O 时被调用
channelUnregistered 当Channel 从它的EventLoop 注销并且无法处理任何I/O 时被调用
channelActive 当Channel 处于活动状态时被调用;Channel 已经连接/绑定并且已经就绪
channelInactive 当Channel 离开活动状态并且不再连接它的远程节点时被调用
channelReadComplete 当Channel上的一个读操作完成时被调用
channelRead 当从Channel 读取数据时被调用
ChannelWritability-Changed 当Channel 的可写状态发生改变时被调用。用户可以确保写操作不会完成得太快(以避免发生OutOfMemoryError)或者可以在Channel 变为再次可写时恢复写入。可以通过调用Channel 的isWritable()方法来检测Channel 的可写性。与可写性相关的阈值可以通过Channel.config().setWriteHighWaterMark()和Channel.config().setWriteLowWater-Mark()方法来设置
userEventTriggered 当ChannelnboundHandler.fireUserEventTriggered()方法被调
用时被调用,因为一个POJO 被传经了ChannelPipeline

bind(ChannelHandlerContext,SocketAddress,ChannelPromise)当请求将Channel 绑定到本地地址时被调用
connect(ChannelHandlerContext,SocketAddress,SocketAddress,ChannelPromise)当请求将Channel 连接到远程节点时被调用
disconnect(ChannelHandlerContext,ChannelPromise)当请求将Channel 从远程节点断开时被调用
close(ChannelHandlerContext,ChannelPromise) 当请求关闭Channel 时被调用
deregister(ChannelHandlerContext,ChannelPromise)当请求将Channel 从它的EventLoop 注销时被调用
read(ChannelHandlerContext) 当请求从Channel 读取更多的数据时被调用
flush(ChannelHandlerContext) 当请求通过Channel 将入队数据冲刷到远程节点时被调用
write(ChannelHandlerContext,Object,ChannelPromise)当请求通过Channel 将数据写到远程节点时被调用

ChannelHandlerAdapter 类的层次结构

ChannelHandlerAdapter提供了实用方法isSharable()返回true,表示它可以被添加到多个ChannelPipeline
中.

DISABLED 禁用泄漏检测。只有在详尽的测试之后才应设置为这个值
SIMPLE 使用1%的默认采样率检测并报告任何发现的泄露。这是默认级别,适合绝大部分的情况
ADVANCED 使用默认的采样率,报告所发现的任何的泄露以及对应的消息被访问的位置
PARANOID 类似于ADVANCED,但是其将会对每次(对消息的)访问都进行采样。这对性能将会有很大的影响,应该只在调试阶段使用

泄露检测级别可以通过将下面的Java 系统属性设置为表中的一个值来定义:

java -D io.netty.leakDetectionLevel=ADVANCED

ChannelPipeline 接口
ChannelPipeline 和它的ChannelHandler
ChannelHandlerContext
ChannelHandlerContext使得ChannelHandler能够和它的ChannelPipeline以及其他的ChannelHandler 交互。ChannelHandler 可以通知其所属的ChannelPipeline 中的下一个ChannelHandler,甚至可以动态修改它所属的ChannelPipeline。ChannelHandlerContext 具有丰富的用于处理事件和执行I/O 操作的API。

在ChannelPipeline 传播事件时,它会测试ChannelPipeline 中的下一个ChannelHandler 的类型是否和事件的运动方向相匹配。如果不匹配,ChannelPipeline 将跳过该ChannelHandler 并前进到下一个,直到它找到和该事件所期望的方向相匹配的为止。(当然,ChannelHandler 也可以同时实现ChannelInboundHandler 接口和ChannelOutboundHandler 接口。)

AddFirst addBefore addAfter addLast 将一个ChannelHandler 添加到ChannelPipeline 中
remove 将一个ChannelHandler 从ChannelPipeline 中移除
replace 将ChannelPipeline 中的一个ChannelHandler 替换为另一个ChannelHandler
get 通过类型或者名称返回ChannelHandler
context 返回和ChannelHandler 绑定的ChannelHandlerContext
names 返回ChannelPipeline 中所有ChannelHandler 的名称

fireChannelRegistered 调用ChannelPipeline 中下一个ChannelInboundHandler 的channelRegistered(ChannelHandlerContext)方法
fireChannelUnregistered 调用ChannelPipeline 中下一个ChannelInboundHandler 的channelUnregistered(ChannelHandlerContext)方法
fireChannelActive 调用ChannelPipeline 中下一个ChannelInboundHandler channelActive(ChannelHandlerContext)方法
fireChannelInactive 调用ChannelPipeline 中下一个ChannelInboundHandler 的channelInactive(ChannelHandlerContext)方法
fireExceptionCaught 调用ChannelPipeline 中下一个ChannelInboundHandler 的exceptionCaught(ChannelHandlerContext, Throwable)方法
fireUserEventTriggered 调用ChannelPipeline 中下一个ChannelInboundHandler 的userEventTriggered(ChannelHandlerContext, Object)方法
fireChannelRead 调用ChannelPipeline 中下一个ChannelInboundHandler 的
channelRead(ChannelHandlerContext, Object msg)方法
fireChannelReadComplete 调用ChannelPipeline 中下一个ChannelInboundHandler 的
channelReadComplete(ChannelHandlerContext)方法fireChannelWritabilityChanged调用ChannelPipeline 中下一个ChannelInboundHandler 的channelWritabilityChanged(ChannelHandlerContext)方法

ChannelPipeline 的出站操作

ChannelPipeline 的出站操作
ChannelHandlerContext 接口

ChannelHandlerContext 代表了ChannelHandler 和ChannelPipeline 之间的关联,每当有ChannelHandler 添加到ChannelPipeline 中时,都会创建ChannelHandlerContext。ChannelHandlerContext 的主要功能是管理它所关联的ChannelHandler 和在同一个ChannelPipeline 中的其他ChannelHandler 之间的交互。

当使用ChannelHandlerContext 的API 的时候,请牢记以下两点:

  • ChannelHandlerContext 和ChannelHandler 之间的关联(绑定)是永远不会改变的,所以缓存对它的引用是安全的;
  • 如同我们在本节开头所解释的一样,相对于其他类的同名方法,ChannelHandler Context的方法将产生更短的事件流,应该尽可能地利用这个特性来获得最大的性能。
Channel、ChannelPipeline、ChannelHandler 以及 ChannelHandlerContext 之间的关系
通过Channel 或者ChannelPipeline 进行的事件传播
注:要想调用从某个特定的ChannelHandler 开始的处理过程,必须获取到在(ChannelPipeline)该ChannelHandler 之前的ChannelHandler 所关联的ChannelHandlerContext。这个ChannelHandlerContext 将调用和它所关联的ChannelHandler 之后的ChannelHandler。
通过ChannelHandlerContext 触发的操作的事件流
消息将从下一个ChannelHandler 开始流经ChannelPipeline,绕过了所有前面的ChannelHandler。
为何要共享同一个ChannelHandler?答:在多个ChannelPipeline中安装同一个ChannelHandler的一个常见的原因是用于收集跨越多个Channel 的统计信息。
异常处理
上一篇下一篇

猜你喜欢

热点阅读