参考https://blog.csdn.net/u011262847/article/details/78713881

每一个Handler都一定会处理出站或者入站(也可能两者都处理)数据,例如对于入站的Handler可能会继承SimpleChannelInboundHandler或者ChannelInboundHandlerAdapter,而SimpleChannelInboundHandler又是继承于ChannelInboundHandlerAdapter,最大的区别在于SimpleChannelInboundHandler会对没有外界引用的资源进行一定的清理,并且入站的消息可以通过泛型来规定。

对于两者关系:

public abstract class SimpleChannelInboundHandler<I> extends ChannelInboundHandlerAdapter

对于ChannelInboundHandlerAdapter的实现,会实现ChannelInboundHandler中的所有方法:

public class ChannelInboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelInboundHandler

但是我们可能只会重写一些我们感兴趣的方法来处理数据,这里使用的是适配器模式

对于SimpleChannelInboundHandler中:

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
boolean release = true;
try {
if (acceptInboundMessage(msg)) {
@SuppressWarnings("unchecked")
I imsg = (I) msg;
channelRead0(ctx, imsg);
} else {
release = false;
ctx.fireChannelRead(msg);
}
} finally {
if (autoRelease && release) {
ReferenceCountUtil.release(msg);
}
}
}
protected abstract void channelRead0(ChannelHandlerContext ctx, I msg) throws Exception;

因此我们继承SimpleChannelInboundHandler后,处理入站的数据我们只需要重新实现channelRead0方法,当channelRead真正被调用的时候我们的逻辑才会被处理。这里使用的是模板模式,让主要的处理逻辑保持不变,让变化的步骤通过接口实现来完成

值得注意的是对于SimpleChannelInboundHandler入站的数据,当被读取之后可能会执行ReferenceCountUtil.release(msg)释放资源。底层是实现ReferenceCounted,当新的对象初始化的时候计数为1,retain()方法实现其他地方的引用计数加1,release()方法实现应用减一,当计数减少到0的时候会被显示清除,再次访问被清除的对象会出现访问冲突。因此,当我们实现自己的Handler的时候如果希望将客户端发送过来的数据发送到客户端,可能在上述finally中已经释放了资源(writeAndFlush是异步处理),所以会出现异常情况。

但是当我们实现的是ChannelInboundHandler类的时候,重写channelRead方法时,需要释放ByteBuf相关的内存,可以使用Netty提供了一个工具方法,ReferenceCountUtil.release()

如果在channelRead中写了ctx.write(接收到的内容),由于write是异步的,可能在channelRead返回之后,仍然没有完成,为此,扩展了ChannelInboundHandlerAdapter,其在这个时间点上不会释放消息,消息在channelReadComplete(),当writeAndFlush方法被调用时释放。

 

SimpleChannelInboundHandler与ChannelInboundHandlerAdapter的更多相关文章

  1. SimpleChannelInboundHandler和ChannelInboundHandlerAdapter区别

    一般用netty来发送和接收数据都会继承SimpleChannelInboundHandler和ChannelInboundHandlerAdapter这两个抽象类,那么这两个到底有什么区别呢? 其实 ...

  2. Netty SimpleChannelInboundHandler和ChannelInboundHandler区别

    一般用netty来发送和接收数据都会继承SimpleChannelInboundHandler和ChannelInboundHandlerAdapter这两个抽象类,那么这两个到底有什么区别呢? 在客 ...

  3. Netty——高级发送和接收数据handler处理器

    netty发送和接收数据handler处理器 主要是继承 SimpleChannelInboundHandler 和 ChannelInboundHandlerAdapter 一般用netty来发送和 ...

  4. 【Netty】(8)---理解ChannelPipeline

    ChannelPipeline ChannelPipeline不是单独存在,它肯定会和Channel.ChannelHandler.ChannelHandlerContext关联在一起,所以有关概念这 ...

  5. netty入门demo(一)

    目录 前言 正文 代码部分 服务端 客服端 测试结果一: 解决粘包,拆包的问题 总结 前言 最近做一个项目: 大概需求: 多个温度传感器不断向java服务发送温度数据,该传感器采用socket发送数据 ...

  6. netty发送和接收数据handler处理器

    netty发送和接收数据handler处理器 主要是继承 SimpleChannelInboundHandler 和 ChannelInboundHandlerAdapter 一般用netty来发送和 ...

  7. Netty(6)关闭

      客户端: public static void main(String[] args) throws Exception { final SslContext sslCtx; if (SSL) { ...

  8. Netty(2)Echo

    上节介绍的是discard协议,即不给客户端返回消息.本节主要说下,echo协议,即服务端收到消息后原样返回给客户端. 为了实现此需求,只需要在DiscardServerHandler中重写chann ...

  9. Netty的常用API(二)

    在使用Netty之前先介绍下Netty的常用API,对其有一个大概的了解. 一.EventLoop和EventLoopGroup EventLoop如同它的名字,它是一个无限循环(Loop),在循环中 ...

随机推荐

  1. java读取properties中文乱码

    1 确认properties文件的编码是utf-8 2 采用流的方式读取文件,设置编码为utf-8 public class ErrorCodeConfig { static Properties p ...

  2. [CQOI2018]破解D-H协议

    嘟嘟嘟 这不就是个bsgs板儿嘛. 顺便就复习了一下bsgs和哈希表. 头一次觉得我的博客这么好用,一下就懂了:数论学习笔记之高次不定方程 这里再补充几点: 1.关于这一段代码: int S = sq ...

  3. SPA游标采集之去除重复

    注:转:http://shsnc2014.blog.163.com/blog/static/2403690822014102411217903/ 当我们做数据库升级项目的时候,我们一般会去做性能回归测 ...

  4. python装饰器(备忘)

    # 装饰器decorator def deco1(fun): def PRINT(*args,**kwargs): print('------deco1------') fun(*args,**kwa ...

  5. ROS 创建服务和请求

    教程 维基 http://wiki.ros.org/cn/ROS/Tutorials 快速过程 创建包 $ cd ~/catkin_ws $ mkdir ~/catkin_ws/src $ cd ~/ ...

  6. 在Windows .NET平台下使用Memcached (Enyim使用)

    1. 启动并配置Memcached的服务端 1. 下载Memcached  http://download.csdn.net/download/ful1021/7969231 2. 解压到任意目录下, ...

  7. 极端恢复时用到的几个隐藏参数 Oracle hidden corruption recovery parameters

    Oracle hidden corruption recovery parameters Note: Oracle hidden parameters are undocumented and uns ...

  8. 【mongoDB查询进阶】聚合管道(一) -- 初识

    https://segmentfault.com/a/1190000010618355 前言:一般查询可以通过find方法,但如果是比较复杂的查询或者数据统计的话,find可能就无能为力了,这时也许你 ...

  9. mac 下利用AndroidStudio APK获取签名信息

    注:网上没找到特别好的.不是xxx.keystore 就是debug.keystore 而真正去找这些目录的时候系统就会提示没有这个秘钥库文件.所以就悲剧了 下面附上快速查看APK签名信息的方法(SH ...

  10. CentOS下安装PHP

    今天終於進行了第三次的在linux下的php安裝,在安裝之前我進行了網站訪問測試. 第一步,先查看mysql.apache這兩項系統服務是否已經自動啟動了,chkconfig –list mysql. ...