您当前的位置:首页 > 互联网百科 > 物联网

开源物联网平台Thingsboard——Netty实现与硬件设备通讯

时间:2020-05-04 16:01:09  来源:  作者:

1.Netty的业务场景

​ 平台主要需求是和充电桩对接,并定时对设备进行监控检查,需要使用Netty作为通信中间件来监听端口,充电桩通过TCP连接向服务端发送指令,后台主要是通过netty的ChannelHandler来实现对硬件数据的接收和处理。

2. Netty的主要组件

2.1 Channel

​ Channel作为Netty网络通信的主体,可以看作是通讯的载体,主要有三个状态:打开、关闭、连接。

​ Channel主要的IO操作:读(read)、写(write)、连接(connect)、绑定(bind),均为异步,也就是说在调用如上方法后,并不保证IO操作完成,但会在IO操作成功、失败或取消后,生成相应的记录保存在一个凭证中并返回。

2.2 ChannelHandler

​ 负责Channel中的逻辑处理,可针对性地拦截处理Channel负责的IO操作或事件,然后在它的ChannelPipeline中将其递交给下一个handler。ChannelHandler中有许多方法需要实现,一般通过继承ChannelHandlerAdapter来实现。

开源物联网平台Thingsboard——Netty实现与硬件设备通讯

 

2.3 ChannelPipeline

​ Netty中,ChannelPipeline相当于ChannelHandler的容器,它们可用于拦截和处理channel事件,关系如下图:

开源物联网平台Thingsboard——Netty实现与硬件设备通讯

 

 

​ ChannelPipeline相当于ChannelHandler的容器,channel事件消息在ChannelPipeline中传播流动,而ChannelHandler可以针对性地对事件进行拦截处理、传递、忽略或者终止。一个ChannelHandler会绑定一个ChannelHandlerContext对象,ChannelHandler会通过与其对应的Context对象和ChannelPipeline交互,比如向上或向下传递events,动态地修改ChannelPipeline,或者通过ChannelHandlerContext中的AttributeKeys存储与handler相关的信息。

3. Netty服务端的启动

	ServerBootstrap serverBootstrap = new ServerBootstrap();    //启动NIO服务的辅助启动类
            serverBootstrap.group(parentGroup, childGroup).channel(NIOServerSocketChannel.class)  //启动服务时, 通过反射创建一个NioServerSocketChannel对象
                    //服务器初始化时执行, 属于AbstracBootstrap的方法
                    .handler(new LoggingHandler(LogLevel.INFO))    //handler在初始化时就会执行,可以设置打印日志级别
                    .option(ChannelOption.SO_BACKLOG, 1024)      //设置tcp缓冲区, 可连接队列大小
                    .option(ChannelOption.SO_REUSEADDR, true)    //允许重复使用本地地址和端口
                    //客户端连接成功之后执行, 属于ServerBootstrap的方法,继承自AbstractBootstrap
                    .childOption(ChannelOption.SO_KEEPALIVE, true)    //两小时没有数据通信时, 启用心跳保活机制探测客户端是否连接有效
                    .childOption(ChannelOption.SO_REUSEADDR, true)
                    .childHandler(serverChannelInit);    //childHandler在客户端成功连接后才执行,实例化ChannelInitializer
            ChannelFuture cf = serverBootstrap.bind(port).sync();    //绑定端口, 添加异步阻塞等待服务器启动完成
            if (cf.isSuccess() == true) {
                logger.info("NettyServer启动成功");
            } else {
                logger.error("NettyServer启动失败", cf.cause());
            }
            cf.channel().closeFuture().sync();    //等待服务器套接字关闭

 

4. Netty中的编解码

4.1 解码器

​ 解码(decode)就是根据约定的协议格式,对二进制数据进行解析解码(decode),这一功能由解码器(decoder)完成。这部分的主要工作是:确定协议、编写协议对应的解码器。Netty中有一套编解码框架,输入的数据由ChannelInboundHandler处理,自定义的解码器实际上就是这个接口的特殊实现类。

​ 对于解码器(decoder),Netty主要提供了抽象基类ByteToMessageDecoder和MessageToMessageDecoder。

开源物联网平台Thingsboard——Netty实现与硬件设备通讯

 

4.1.1 抽象类ByteToMessageDecoder

​ 用于将接收的二进制数据(Byte)解码,得到完整有效的请求报文(Message)。

​ 一般ByteToMessageDecoder解码内容后,会得到一个ByteBuf实例,每个ByteBuf实例都包含了一个完整的报文信息。可以直接把这些ByteBuf实例交给之后的ChannelInboundHandler处理,或将ByteBuf实例解析封装到不同的JAVA实例对象后,再交给它处理。不管哪一种情况,之后的ChannelInboundHandler在处理时不需要再考虑粘包、拆包问题。

​ ByteToMessageDecoder中常见的实现类:

FixedLengthFrameDecoder:定长协议解码器,可以指定固定字节数算一个完整报文

LineBasedFrameDecoder:行分隔符解码器,遇到n或者rn,则认为是一个完整的报文

DelimiterBasedFrameDecoder:分隔符解码器,与LineBasedFrameDecoder类似,但可以自己指定分隔符

LengthFieldBasedFrameDecoder:长度编码解码器,将报文划分为报文头/报文体,根据报文头中的Length字段确定报文体的长度,因此报文体的长度是可变的

JsonObjectDecoder:json格式解码器,当检测到匹配数量的"{" 、”}”或”[””]”时,则认为是一个完整的json对象或json数组

这些实现类,都只是将接收到的二进制数据解码,转成ByteBuf实例后直接交给之后的ChannelInboundHandler处理,并没有将ByteBuf实例中的信息封装到Java对象中,因为Netty并不清楚报文具体内容,以及需要封装到哪个Java对象,所以需要自己手动来解析ByteBuf实例并封装。

​ 可以自定义一个解码类继承ByteToMessageDecoder抽象类,重写它的decode方法:

protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception;

​ 参数列表:

ByteBuf in:解码前的二进制数据

List out:解码后的有效报文列表,由于tcp可能出现的粘包问题,入参的in中可能含有多个有效报文,所以需要将解码后的报文添加到List中,或者可能出现拆包,那么in中的数据就不足以构成一个有效报文,这时无需向List中添加元素。

​ 解码时需要尤其注意的是,应该先判断是否能构成一整个有效报文,再调用ByteBuf的read方法来读取数据,通过与in.readableBytes比较,来判断in中可读字节数是否大于约定的基本数据帧长度,只有在大于等于的情况下,我们才进行解码,即读取指定长度的字节,添加到List中。

4.1.2 抽象类MessageToMessageDecoder

​ 用于将一个本身就包含完整报文信息的对象转成另一个Java对象。

​ ByteToMessageDecoder解码后将包含了报文信息的ByteBuf实例交给后面的ChannelInboundHandler处理,此时可以在ChannelPipeline中再添加一个MessageToMessageDecoder,将ByteBuf中的信息解析后封装到Java对象中,简化接下来的ChannelInboundHandler操作。或者是要将已经封装好的Java对象转成其他Java对象,所以会出现MessageToMessageDecoder之后接着另一个MessageToMessageDecoder的情况。比如,Tomcat将浏览器发送过来的二进制数据解析为HttpServletRequest对象后,我们还需要将其中的数据提取出来封装成自定义的POJO类,即将现有的Java对象(HttpServletRequest)转换成另一个Java对象(POJO类)。

​ 继承MessageToMessageDecoder抽象类,也是要重写它的decode方法:

protected abstract void decode(ChannelHandlerContext ctx, I msg, List<Object> out) throws Exception;

​ 参数列表:

I msg:配置需要进行解码的参数

List out:经过MessageToMessageDecoder解析后,得到的Java对象存入列表

​ 那么在ChannelPipieline中它们的处理顺序如下:

ChannelPipieline ch=...
ch.addLast(new ByteToMessageDecoder());//ByteToMessageDecoder实现类
ch.addLast(new MessageToMessageDecoder());//MessageToMessageDecoder实现类
ch.addLast(new MessageToMessageDecoder());
...

 

​ 需要注意的是,即便是指定MessageToMessageDecoder的传入类型为ByteBuf,也绝对不可以用它来代替ByteToMessageDecoder报文解析的工作,因为ByteToMessageDecoder的内部设计才是针对接收到的二进制数据进行解码,所以除了解码,它其中还有对尚不完整的报文进行拆包缓存的功能逻辑,这是MessageToMessageDecoder所不具备的。

​ 因此,通常会先用ByteToMessageDecoder解析报文以及粘拆包处理,得到完整有效的ByteBuf实例,之后再交由一个或多个MessageToMessageDecoder对ByteBuf实例中的数据进行解析并封装成POJO类。

4.2 编码器

​ 相对应地,在ChannelOutboundHandler接口下,Netty也提供了MessageToByteEncoder和MessageToMessageEncoder两个抽象类来完成编码。没有解码器的内部逻辑复杂,编码只要将数据转成约定的二进制格式发送即可,而解码器除了解析数据,还要处理粘拆包问题。

4.3 编码解码器Codec

​ Codec同时具备编解码功能,它同时实现了ChannelInboundHandler和ChannelOutboundHandler两个接口,因此数据的输入输出都能处理。

​ Netty提供了一个ChannelDuplexHandler适配器类,编解码器的抽象基类ByteToMessageCodec和MessageToMessageCodec都继承了它,整体继承关系如下:

开源物联网平台Thingsboard——Netty实现与硬件设备通讯

 

​ ByteToMessageCodec中维护了一个ByteToMessageDecoder和一个MessageToByteEncoder实例,结合二者的功能,泛型参数I可指定接受的编码类型:

public abstract class ByteToMessageCodec<I> extends ChannelDuplexHandler {
    private final TypeParameterMatcher outboundMsgMatcher;
    private final MessageToByteEncoder<I> encoder;
    private final ByteToMessageDecoder decoder = new ByteToMessageDecoder(){…}
  
    ...
    protected abstract void encode(ChannelHandlerContext ctx, I msg, ByteBuf out) throws Exception;
    protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception;

 

MessageToMessageCodec中维护了一个MessageToMessageDecoder和一个 MessageToMessageEncoder实例,结合二者的功能,泛型参数INBOUND_IN和OUTBOUND_IN分别表示需要解码和编码的数据类型:一个简单的总结:ByteToMessageCodec和MessageToMessageCodec中分别实现了字节和对象之间、对象和对象之间的编解码。



Tags:物联网   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
大家好,我是志明。上一期我们聊了物联网的发展。今天我想和大家聊一聊物联网(IOT)的落地应用:共享设备。 相信各位对这个词并不陌生,随着互联网技术的快速发展,以共享设备为代表的...【详细内容】
2021-12-24  Tags: 物联网  点击:(18)  评论:(0)  加入收藏
随着物联网设备数量的持续增加,这些设备之间的通信或连接已成为一个重要的思考课题。通信对物联网来说十分常用且关键,无论是近距离无线传输技术还是移动通信技术,都影响着物联...【详细内容】
2021-12-16  Tags: 物联网  点击:(16)  评论:(0)  加入收藏
安科瑞 于洋 周洁摘要:现代物联网技术高速发展,许多场所已经开始合理应用物联网照明系统,作为工厂生产的重要因素之一,工厂照明系统的智能化控制可以有效提高工厂对能源的利用率...【详细内容】
2021-12-14  Tags: 物联网  点击:(20)  评论:(0)  加入收藏
来源:内容由半导体行业观察(ID:icbank)来自Ctimes,谢谢。在数字化实体世界中,物联网技术的应用相当广泛,市场潜能与商机庞大。麦肯锡(MGI)《物联网:超越市场炒作价值(The Internet o...【详细内容】
2021-11-30  Tags: 物联网  点击:(20)  评论:(0)  加入收藏
SpringBoot开发的物联网通信平台系统项目功能模块 功能 说明 MQTT 1.SSL支持 2.集群化部署时暂不支持retain&will类型消 UDP ...【详细内容】
2021-11-05  Tags: 物联网  点击:(56)  评论:(0)  加入收藏
物联网(IoT)行业正蓬勃发展,成功的物联网项目需要大量工程,本文讨论了完整物联网项目所需的开发人员技能:包括嵌入式开发技术,应用程序编程,大数据分析等等。硬件设计师大多数物...【详细内容】
2021-11-03  Tags: 物联网  点击:(29)  评论:(0)  加入收藏
M2M我的一般的理解就是机器到机器(Machine to Machine),点对点的机器链接。从概念上也可以理解为人到人(Man to Man)、人到机器(Man to Machine)。即时通信工具就是人到人的交互,人...【详细内容】
2021-10-29  Tags: 物联网  点击:(72)  评论:(0)  加入收藏
在这篇文章中,大家将了解MQTT协议,以及为什么在许多物联网应用中使用它。 MQTT协议最初由IBM开发,并且是专有的。它的开发是为了解决石油和天然气行业的传感器通过卫星与远程服...【详细内容】
2021-10-21  Tags: 物联网  点击:(32)  评论:(0)  加入收藏
WiFi发展至今已有20多年的历史,WiFi模组就已经不是一个新兴概念。随着国内市场上智能硬件的成长,WiFi迎来了"爆发式"增长,这也意味着WiFi模组找到了春天。无线通信模块的价值主...【详细内容】
2021-07-20  Tags: 物联网  点击:(106)  评论:(0)  加入收藏
背景介绍在 IoT 物联网场景中,因为消费者分布全球各地,设备会被销售到多个国家或地区使用。 如果需要通过某个固定的服务器,远程管理多个国家或地区的设备,那么可能会出现如下情...【详细内容】
2021-07-16  Tags: 物联网  点击:(80)  评论:(0)  加入收藏
▌简易百科推荐
大家好,我是志明。上一期我们聊了物联网的发展。今天我想和大家聊一聊物联网(IOT)的落地应用:共享设备。 相信各位对这个词并不陌生,随着互联网技术的快速发展,以共享设备为代表的...【详细内容】
2021-12-24  物联网系统开发大观    Tags:物联网   点击:(18)  评论:(0)  加入收藏
随着物联网设备数量的持续增加,这些设备之间的通信或连接已成为一个重要的思考课题。通信对物联网来说十分常用且关键,无论是近距离无线传输技术还是移动通信技术,都影响着物联...【详细内容】
2021-12-16  pheenet菲尼特    Tags:物联网   点击:(16)  评论:(0)  加入收藏
安科瑞 于洋 周洁摘要:现代物联网技术高速发展,许多场所已经开始合理应用物联网照明系统,作为工厂生产的重要因素之一,工厂照明系统的智能化控制可以有效提高工厂对能源的利用率...【详细内容】
2021-12-14  安科瑞于洋    Tags:物联网   点击:(20)  评论:(0)  加入收藏
来源:内容由半导体行业观察(ID:icbank)来自Ctimes,谢谢。在数字化实体世界中,物联网技术的应用相当广泛,市场潜能与商机庞大。麦肯锡(MGI)《物联网:超越市场炒作价值(The Internet o...【详细内容】
2021-11-30  半导体行业观察    Tags:物联网   点击:(20)  评论:(0)  加入收藏
计讯物联无线数传终端DTU,对接充电桩与后端管理中心,多量分散充电桩统一集中管控,工业设计,无线部署、远程状态监测。  无线DTU充电桩联网  1、无线数据终端DTU建立充电桩...【详细内容】
2021-11-05  物联界的程序猿    Tags:充电桩   点击:(40)  评论:(0)  加入收藏
物联网(IoT)行业正蓬勃发展,成功的物联网项目需要大量工程,本文讨论了完整物联网项目所需的开发人员技能:包括嵌入式开发技术,应用程序编程,大数据分析等等。硬件设计师大多数物...【详细内容】
2021-11-03  粤嵌教育    Tags:物联网   点击:(29)  评论:(0)  加入收藏
M2M我的一般的理解就是机器到机器(Machine to Machine),点对点的机器链接。从概念上也可以理解为人到人(Man to Man)、人到机器(Man to Machine)。即时通信工具就是人到人的交互,人...【详细内容】
2021-10-29  喻喻嗒    Tags:物联网   点击:(72)  评论:(0)  加入收藏
在这篇文章中,大家将了解MQTT协议,以及为什么在许多物联网应用中使用它。 MQTT协议最初由IBM开发,并且是专有的。它的开发是为了解决石油和天然气行业的传感器通过卫星与远程服...【详细内容】
2021-10-21  亿佰特物联网实验室    Tags:MQTT   点击:(32)  评论:(0)  加入收藏
介绍IconPark是字节跳动团队开源的一个开源图标库,一共提供超过2000个高质量的图标,提供可视化界面配置来实现不同的方案,非常适合开发者和设计师来使用! GithubGitHub:https://...【详细内容】
2021-07-19  爱分享Coder    Tags:IconPark   点击:(189)  评论:(0)  加入收藏
背景介绍在 IoT 物联网场景中,因为消费者分布全球各地,设备会被销售到多个国家或地区使用。 如果需要通过某个固定的服务器,远程管理多个国家或地区的设备,那么可能会出现如下情...【详细内容】
2021-07-16  公田    Tags:物联网   点击:(80)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条