参考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. sqlserver 2000数据压缩解决方法

    --sqlserver 2000数据压缩解决方法. /************************************************************************* ...

  2. css3 object-fit详解

    上传头像的时候遇到了头像变形的问题,最后通过object-fit: cover完美解决了.这个CSS属性可以达到最佳最完美的居中自动剪裁图片的功能. object-fit理解 CSS3 backgro ...

  3. re库

    一.Re库的主要功能: 函数 功能 re.search() 在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象 re.match() 在一个字符串的开始位置匹配正则表达式,返回match ...

  4. dbms_redefinition方式普通表改造分区表

    --创建一张普通表t_wjq1SEIANG@seiang11g>create table t_wjq1 as select object_id,object_name,created from ...

  5. [LeetCode]最大系列(最大正方形221,最大加号标志764)

    221. 最大正方形 题目描述: 在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积. 示例: 输入: 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 ...

  6. ubuntu 学习

    参考博客:http://www.cnblogs.com/resn/p/5800922.html 在Linux 里一切皆文件 / : 根 查看是否安装了中文支持:locale -a 如果有zh_CN.u ...

  7. oracle sys_guid

    select sys_guid() from dual;

  8. git分支开发的好处

    有不少开发者们不习惯使用Git分支开发.原因有如下几个方面?(1)不熟悉不习惯;(2)觉得太麻烦;今天我想说的是使用git分支开发绝对是一个高效版本控制的做法. 当你遇到测试人员给你提的bug,你只需 ...

  9. eclipse如何设置断点&断点处运行快捷键

    第一步: 设置断点:在该行最前面边框双击  或快捷键:Ctrl+Shift+B   第二步: Debug 运行启动   第三部: 运行到断点后: 使用快捷键F5,F6,F7单步执行. F5:Step ...

  10. UOJ236 IOI2016 Railroad 差分、欧拉回路、最小生成树

    传送门 将"进入路段时速度\(\leq s_i\)"转换为:"进入路段时速度恰好等于\(s_i\),并且铺设铁轨有加速和减速两种,加速无需代价,减速每\(1 km/h\) ...