本文最后更新于:June 30, 2023 pm

本文作者:[wangwenhai] # 概要:用Erlang实现一个精简的基于TCP协议之上的应用层协议。


1. 设计背景

​ 看到TRUMP大家首先想到的是一头飘逸金发,胸前飘着鲜艳红领带的老年人,没错就是下面这个:

image-20200519103707805

​ 但是今天我说的这个TRUMP和上面这位半毛钱关系都没有。我的TRUMP有单独的含义,我给出的这个TTUMP是一种简单的客户端-服务端的通信协议。下面是TRUMP的完整名称:

TRUMP:TCP Remix UDP Middle Protocol(中文释义:TCP混合UDP的中间层协议)

乍一看像是在卖关子,其实是有严格的定义和说明的,下面我解释一下为何要定义这么奇怪的一个名字。

​ 近期在家里看着墙发呆的时候,闹钟引起了我的注意。这个闹钟是大学的时候用过的,一直到现在都还在正常显示,突然想起来上一次换时间貌似是2017年12月–一个冬天,现在都2020年了,拿过来摆弄了一番,发现里面装了3节南孚电池。令我惊讶的是,闹钟还能很大声的响铃。

​ 我不由得来了兴趣,仔细分析了一下这个闹钟的基本构造。闹钟用了液晶数码管作为显示屏,而液晶数码管的功耗就非常低了,这节省了很大的电量。同时有3节7号电池供电,电压是1.5*3=4.5V,差不多工作电流是0.001MA(百度了一下基本的参数做了对比),在如此低功耗条件下工作了快2年,确实值得研究。

​ 于是我想了一下,能不能发明一个专门针对低功耗的芯片的通信协议,来实现以非常低的功率长时间工作。最好是纽扣电池,或者是马铃薯、番茄电池都能维持通信。我的闹钟上面可以显示温湿度,如果加以改造,就可以把这些数据上传到云服务器,岂不是可以时刻监控温湿度而实现动态调节?同时我还想远程换个铃声,这又涉及到了远程及时通信了,在这个比较有趣的情景下,我决定发明一个简单的,但是靠谱的,针对低端尤其是低功耗的设备进行少量数据传输的协议。

​ 其实一开始叫Trap,可能我觉得我的能力不够,做出来的东西就是个坑(Trap)吧,为了避免过分解读和吐槽,简单定义为:一个简单的玩具协议。

​ 最近我又重新梳理了一下,把一些比较核心的概念还有设计思路捋清楚,然后认证整理出来。Trap是之前设计的一个不完善的协议,所以这次相对比较完善,为了区分,重新更名为:TRUMP。

​ TRUMP的核心是同时支持基于原生TCP(Raw TCP)和原生UDP(Raw UDP)两种类型的通信形式,对于这两种传输层协议做了最简单的封装,故命名为中间层协议(Middle Protocol)。

​ 本协议的设计相对来讲比较通俗易懂,都是基础知识,可以为初学者提供一些设计思路,这些思路可以用在游戏开发,IM开发,还有物联网终端通信等等,其实就是提供了一个把传输层往应用层靠拢的最基础的思路。

​ 该设计当然是不完善的,远远达不到工业级的水准,所以各位朋友如果发现问题或者设计思路有大问题,可以指出。但是不接受喷子和高论,如果某个大佬有高论或者更优秀的设想,请自己亲自实现一遍比较好。

​ 讲文明树新风,文明社会树立文明形象。

2. 参照标准

​ 在设计之前,我参考了好几种常见的协议,站在巨人的肩上工作能无限接近天花板不是吗。
近期参考了EMQ的一些设计思路(尤其是EMQ的产品介绍PPT),还有之前的一个TCP服务器Demo也给了我一定程度的启发,EMQ给我的思路是:通信需要并发处理,TCP服务器Demo给我的思路是:越简单越好,这句话也是Python之禅的名言。
​ 我协议设计的主要思路来源于Erlang的TCP并发处理模式和低功耗的芯片通信。

3. 同类协议

3.1 COAP协议

​ CoAP(Constrained Application Protocol)是一种在物联网世界的类HTTP协议,它的详细规范定义在 RFC 7252。COAP名字翻译来就是“受限应用协议”,顾名思义,使用在资源受限的物联网设备上。物联网设备的资源很受限,运行HTTP是不可以接受的。
COAP是一个非常简单的协议,非常轻量级,甚至可以看作是HTTP的精简版(当然和HTTP区别很大)。

3.2 MQTT协议

​ MQTT 全称为 Message Queuing Telemetry Transport(消息队列遥测传输)是一种基于发布/订阅范式的“轻量级”消息协议,由 IBM 发布。MQTT 可以被解释为一种低开销,低带宽占用的即时通讯协议,可以用极少的代码和带宽的为连接远程设备提供实时可靠的消息服务,它适用于硬件性能低下的远程设备以及网络状况糟糕的环境下,因此 MQTT 协议在 IoT(Internet of things,物联网),小型设备应用,移动应用等方面有较广泛的应用。
​ MQTT 可以看作是TCP之上的一个高级封装协议,功能强大,很适合作为物联网设备采集数据使用的协议。
关于其他的就不赘述了,上面介绍这两种协议最终目的就是让大家看到一个共同之处:物联网世界的通信大部分是:低功率、条件受限,资源不足。我们就按照这个设计思路出发设计新的协议,能同时支持TCP和类CoAP协议的协议,简单来说是简单合体又比单独两个协议更有趣(不是取代,也不是挑战,而是另一种思路,给学习者带来一种心情的愉悦)的简单协议。

4. 协议规范

​ TRUMP协议其实是2个模式组成的:TCP模式和UDP模式,TRUMP有一个固定数据报文头,数据固定报文头使用4个字节(byte)来表示,如下表所示:

image-20200519104508811

· 字节0表示消息报文类型编码,具体看附表;
· 字节1、2字节表示消息的长度(Byte),最长支持65536(Byte)个字符,也就是64KB,最长只能发送64KB数据;
· 字节3为扩展字节,预留给其他报文使用。分为高四位和低四位,主要用来传递客户端ID的长度。客户端ID长度最长为4位,也就是16个字符。当单个客户端的时候,ID在低四位,如果是客户端之间的通信,ID在高四位,而对端ID是低四位。

注意:因为服务端支持分布式,所以ID不可重复,必须是整个节点群内的唯一值。

5. 模式选择

5.1 Trap模式

​ TRAP模式是原生TCP的简单封装,专门用在实时通信的情况下,例如实时控制。下面是TRAP模式的设计规范。
​ TRAP最大的特征是可以保持数据的可达性,也就是只要发出去的数据,一定会到达对端,不论是服务器还是客户端。假如说对端不在线,服务器会保存下来,当客户端上线的时候第一时间发布过去。

5.2 Urap模式

​ URAP模式是原生UDP的简单封装,专门用在非实时通信的情况下,例如设备简单的数据采集,IM聊天推送等等。URAP模式下,客户端可以进行的操作和TRAP一样,但是比较重要的是:服务端不保证数据可达性,也就是如果对端不存在,会直接丢弃消息。因此需要客户端来保存失败的数据。

6. 发布-订阅

​ 除此之外,TrumpServer为了方便开发的时候一些需求,增加了PUB-SUB插件功能,类似于Mqtt协议那样的形式,但是相对来讲比较简单。适合用在小型设备之间的网络通信。

image-20200519113539690

7. 内存数据库

​ 新增加插件功能:内存数据库,本插件是一个K-V类型的数据库,提供TCP客户端和HTTP接口,用法类似于Redis,但是功能简单,针对特殊场景,一般计划用在设备临时存放数据,当单片机的ROM或者RAM不够的情况下,可以把数据临时存放上来。

image-20200519113938941

8.资源链接


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

1.3基础语法 Previous
日常操作记录 Next