SimpleChannelInboundHandler与ChannelInboundHandlerAdapter
参考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的更多相关文章
- SimpleChannelInboundHandler和ChannelInboundHandlerAdapter区别
一般用netty来发送和接收数据都会继承SimpleChannelInboundHandler和ChannelInboundHandlerAdapter这两个抽象类,那么这两个到底有什么区别呢? 其实 ...
- Netty SimpleChannelInboundHandler和ChannelInboundHandler区别
一般用netty来发送和接收数据都会继承SimpleChannelInboundHandler和ChannelInboundHandlerAdapter这两个抽象类,那么这两个到底有什么区别呢? 在客 ...
- Netty——高级发送和接收数据handler处理器
netty发送和接收数据handler处理器 主要是继承 SimpleChannelInboundHandler 和 ChannelInboundHandlerAdapter 一般用netty来发送和 ...
- 【Netty】(8)---理解ChannelPipeline
ChannelPipeline ChannelPipeline不是单独存在,它肯定会和Channel.ChannelHandler.ChannelHandlerContext关联在一起,所以有关概念这 ...
- netty入门demo(一)
目录 前言 正文 代码部分 服务端 客服端 测试结果一: 解决粘包,拆包的问题 总结 前言 最近做一个项目: 大概需求: 多个温度传感器不断向java服务发送温度数据,该传感器采用socket发送数据 ...
- netty发送和接收数据handler处理器
netty发送和接收数据handler处理器 主要是继承 SimpleChannelInboundHandler 和 ChannelInboundHandlerAdapter 一般用netty来发送和 ...
- Netty(6)关闭
客户端: public static void main(String[] args) throws Exception { final SslContext sslCtx; if (SSL) { ...
- Netty(2)Echo
上节介绍的是discard协议,即不给客户端返回消息.本节主要说下,echo协议,即服务端收到消息后原样返回给客户端. 为了实现此需求,只需要在DiscardServerHandler中重写chann ...
- Netty的常用API(二)
在使用Netty之前先介绍下Netty的常用API,对其有一个大概的了解. 一.EventLoop和EventLoopGroup EventLoop如同它的名字,它是一个无限循环(Loop),在循环中 ...
随机推荐
- centos7下安装docker(22.docker swarm-----service)
运行service 执行以下命令: docker service create --name web-server httpd 通过docker service ls查看swarm中的service ...
- js按照特定的中文字进行排序的方法
之前遇到过按照中文字符排序的需求很顺利的解决了,这次是按照特定的中文字进行排序,比如按照保守型,稳健型,平衡型,成长型,进取型进行排序. 可以使用localeCompare() 方法来实现中文按照拼音 ...
- day 07 字符编码
一:字符编码 1.字符编码 什么是字符编码:将人能识别的字符转换为计算机能识别的01二进制的过程就是字符编码,转换的规则就是字符编码表 常用的编码表:ASCII.GBK.Unicode.UTF-8 了 ...
- day09--函数的定义分类以及其使用(1)
一.函数的定义以及分类: 什么是函数:函数是可以重复调用来完成特定功能的代码块.-----(重复利用的工具) """ 1 什么是函数?重复利用的工具————可以完成特定功 ...
- JSONPath介绍
1. JSONPath介绍 官网地址: https://github.com/alibaba/fastjson/wiki/JSONPath fastjson 1.2.0之后的版本支持JSONPath. ...
- pyspider环境部署1--python3安装
爬虫是一个既好玩又好用的东西,接触它有1年多了,了解一些,算不上精通.爬过新闻.微信公众号,主要用pyspider,scrapy也了解过,python2和3都尝试过.公司业务规模不大,基于 pytho ...
- 论文笔记---Deblurring Shaken and Partially Saturated Images
抖动和部分饱和图像去模糊 摘要 我们解决了由相机抖动造成的模糊和饱和或过度曝光像素导致的图像去模糊的问题.饱和像素对于现有的非盲去模糊算法是一个问题,因为它们不符合图像形成过程是线性的这一假设,并且经 ...
- 算法相关——Java排序算法之希尔排序(五)
个子块,即{3,5},{1,0},{5,2},{9,4},{6,12},将每个子块进行插入排序(即第i位与第i+5位进行比较交换),初步排序结果为{3,0,2,4,6,5,1,5,9,12}.希尔排序 ...
- 深入理解JAVA虚拟机(内存模型+GC算法+JVM调优)
目录 1.Java虚拟机内存模型 1.1 程序计数器 1.2 Java虚拟机栈 局部变量 1.3 本地方法栈 1.4 Java堆 1.5 方法区(永久区.元空间) 附图 2.JVM内存分配参数 2.1 ...
- MySQL表结构变更,不可不知的Metadata Lock
在线上进行DDL操作时,相对于其可能带来的系统负载,其实,我们最担心的还是MDL其可能导致的阻塞问题. 一旦DDL操作因获取不到MDL被阻塞,后续其它针对该表的其它操作都会被阻塞.典型如下,如阻塞稍久 ...