Skip to content

webVueBlog/spring-iot-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

技术选型

在Java界做socket开发最好的框架就是Netty,一个基于nio的封装,并解决了在Linux环境下nio的一些已知BUG。理想情况下前置程序应该只负责终端设备的连接保持和数据的转发,具体的业务交由后置程序来实现处理。

  • Netty在最前端负责接收连接请求和上下行数据,实验数据使用1G内存docker容器运行,一个容器可以保持并处理5万个终端的连接。
  • 为了加快Netty的处理速度,从终端接收上来的数据会直接放到disruptor内存队列中。
  • disruptor的消费者会根据数据的类型来选择,注册终端、通过rabitmq向后置处理程序提交、通过kafka向后置提交日志
  • 同时还需要做基本的心跳检查

通讯协议设计

通许协议的设计主要从几个方面考虑:

  1. 首先要能解决TCP的粘包、半包问题
  2. 通讯数据量要尽可能的小,终端设置的物联卡一般流量包都不会太大。
  3. 编码格式,目前一般都使用UTF8格式

为了解决第一问题,一般协议会考虑使用:

  1. 定长数据包方案优点是处理简单,缺点是为了照顾大数据包。会存在大量包里携带空数据。适合比较简单的数据/控制
  2. 特定字符分割方式。大多采用\n来分包,比第一种相对灵活。比如redis的通许就是用的这种
  3. 首字节指定包长度方式。大量基于C开发的终端设备在使用,相对第一种更灵活不浪费流量
  4. 闭合包方式,最就是目前互联网协议里用的最多的json。可以使用基础器来找{}的匹配,优点时通用性好,缺点是多少会浪费流量。

如果终端程序和服务端都是自行开发,推荐使用谷歌家的protobuf,Netty有良好的支持。如果双终端是第三方开发的为了降低联调难度推荐使用json。这次我们选择使用Json来进行设计我们的协议

业务 请求 应答 备注
登录 {"msgType": 10, "devId": "11010112345", "version":"1.0", "txNo": "1234567890123", "sign": "md5(devId+txNo+key)"} {"msgType": 11, "result": 1, "txNo": "1234567890123"} 终端=>服务器
心跳 {"msgType": 20, "txNo": "1234567890123"} {"msgType": 21, "txNo": "1234567890123"} 双向
控制 {"msgType": 30, "txNo": "1234567890123", "data": ""} {"msgType": 31, "txNo": "1234567890123", "result":""} 服务器=>终端
数据上报 {"msgType": 40, "txNo": "1234567890123", "data": ""} {"msgType": 41, "txNo": "1234567890123"} 终端=>服务器
注销 {"msgType": 50, "txNo": "1234567890123" } {"msgType": 51, "txNo": "1234567890123" } 双向,主动断开链接

说明:

  1. txNo为唯一序号,使用13位时间戳即可,应答时带回同一个时间戳即可。
  2. 登录接口里的sign主要是为了防止接口泄漏后,有人恶意请求接口模拟设备踢掉真实设备
  3. 心跳包 从服务器向终端时,终端如果无法跑NTP协议可以用此包里的txno做校时
  4. 注销功能主要 是为了客户端正常下线使用。减少服务器保持连接的时间减少资源占用。

About

基于Netty实现的一个物联网服务端程序

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published