参考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的类是单继承的,接口是多继承的

    类 如果一个类继承了两个类,但是这两个类中有相同的方法,那么子类调用方法时,无法确定应该调用哪个父类的方法. [c++是多继承的] 接口 jdk1.7  接口可以多继承,是因为当接口中是抽象方法.不存 ...

  2. C#释放资源文件dll或exe

    将程序包含的资源文件释放到硬盘上 1.VS2017-新建  winform(窗体应用)命名为 loader 2.在解决方案管理器中,展开项目loader 在 properties 下面,找到[Reso ...

  3. Spring Cloud Config(配置中心)

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 一.简介 Spring Cloud Config为分布式系统中的外部配置提供服务器和客 ...

  4. sql优化的几种方法

    在sql查询中为了提高查询效率,我们常常会采取一些措施对查询语句进行sql优化,下面总结的一些方法,有需要的可以参考参考. 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ord ...

  5. 08 python 初学(字典)

    字典是 python 中唯一的映射类型 .采用键值对(key-value)的形式存储数据. python 对 key 进行哈希函数运算,根据计算的结果决定 value 的存储地址,所以字典时无需存储的 ...

  6. ElasticSearch(站内搜索) 转发 https://www.cnblogs.com/xibei666/p/5929970.html

    简介 Elasticsearch是一个实时的分布式搜索和分析引擎.它可以帮助你用前所未有的速度去处理大规模数据.它可以用于全文搜索,结构化搜索以及分析,当然你也可以将这三者进行组合.Elasticse ...

  7. 转发 .Net平台下ActiveMQ入门实例 https://www.cnblogs.com/madyina/p/4121458.html

    1.ActiveMQ简介 先分析这么一个场景:当我们在网站上购物时,必须经过,下订单.发票创建.付款处理.订单履行.航运等.但是,当用户下单后,立即跳转到“感谢那您的订单” 页面.不仅如此,若果没有延 ...

  8. 初学Python——列表生成式、生成器和迭代器

    一.列表生成式 假如现在有这样一个需求:快速生成一个列表[1,2,3,4,5,6,7,8,9,10],该如何实现? 在不知道列表生成式的情况下,可能会这样写: a=[1,2,3,4,5,6,7,8,9 ...

  9. HyperLedger Fabric 1.0的Transaction处理流程

    如果把区块链比作一个只能读写,不能删改的分布式数据库的话,那么事务和查询就是对这个数据库进行的最重要的操作.以比特币来说,我们通过钱包或者Blockchain.info进行区块链的查询操作,而转账行为 ...

  10. CentOS下安装Apache

    CentOS下安装Apache,首先在用户状态下使用su root命令切换到超级管理员界面,让后开启终端,进行apache的安装过程. [root@localhost centos]# yum ins ...