channelHandler 在Netty 4.x版本有了至关大的改动html
http://netty.io/wiki/new-and-noteworthy.html 官网的更新改进说明。promise
如下节选官网更新说明的部分中文翻译:ide
“spa
在3.x时代,全部的I/O操做都会建立一个新的ChannelEvent对象。对每一个读或写的操做,还会额外建立一个新的ChannelBuffer对象。因为将资源管理和buffer的池化交给了JVM,这实际上极大地简化了Netty的内部实现。可是,基于Netty开发的应用在高负载下运行时,有时会观察到GC(Garbage Collection)的压力增大或变化不定,这些问题的根源也来自于这里。翻译
4.0经过把事件对象替换为直接与类型相对应(译者注:原文为strongly typed,可是我以为直译为强类型不太容易理解)的方法调用,几乎彻底避免了事件对象的建立。3.x中,有相似于handleUpstream()和handleDownstream()这种可以捕获全部相关类型事件的处理器方法,4.0中你将不会再看到它们的身影了。全部的事件类型如今都有各自对应的处理器方法:设计
“3d
”全部这些变化意味着用户没法去扩展ChannelEvent这个已经不存在的接口了。那用户要怎样才能定义他或她本身的事件类型呢,就像IdleStateEvent?4.0中的ChannelHandler有一个处理器方法叫作userEventTriggered(),它就是被设计用来知足这种特殊的用户需求。netty
“code
4.x版本中简化了channel 状态模型(Simplified channel state model):htm
3.x版本的:
在4.x版本中:
ChannelOpen ChannelBound 和ChannelConnected 合并到ChannelActive.ChannelDisconnected ChannelUnbound ChannlClosed合并到ChannelInactive中
以下图所示:
在Netty4.0.12的源代码中咱们能够看到AbstractChannel中的:
AbstractUnsafe{
...//调用fireChannelActive()
private void register0(ChannelPromise promise)
public final void bind(final SocketAddress localAddress, final ChannelPromise promise)
...//调用fireChannelInactive()
public final void disconnect(final ChannelPromise promise)
public final void close(final ChannelPromise promise)
}
..值得注意的是官网还特地提示了ChannelRegister和ChannelOpen和ChannelClosed有很大的区别
引入翻译:"channelRegistered和channelUnregistered这两个事件与channelOpen和channelClosed具备的意义是不同的。它们(channelRegistered和channelUnregistered)是在支持Channel的动态注册、注销以及再注册时被引入的"
如图所示。注册和注销仅仅用于每次的操做。
如下是我的口水:
貌似这么作的好处在于。把channel的异常放在一个方法内统一处理。在3.x的开发过程当中发现。不少时候咱们想要的只是一个结果。服务端数据在客户端channel断开链接。解绑定。关闭3中状态时,须要将相对应的信息数据处理掉。在4.x版本中将这三个事件整合以后。只须要统一的处理就行了。
1 // 管道从不活跃状态 转到 活跃状态 触发 2 @Override 3 public void channelActive(ChannelHandlerContext ctx) throws Exception { 4 final Channel channel = ctx.channel(); 5 if(channel.isOpen()){ 6 // 管道 活跃的 而且是开启状态 7 } 8 super.channelActive(ctx); 9 } 10 11 // 管道从活跃状态 转到 不活跃状态 触发 12 @Override 13 public void channelInactive(ChannelHandlerContext ctx) throws Exception { 14 15 Channel channel = ctx.channel(); 16 if(!channel.isOpen()){ 17 18 19 } 20 super.channelInactive(ctx); 21 }