作者:张裕鹏 日期:2021-7-21
0. 前言
0.1. 为什么需要有物联网协议?
- 为了实现万物互联,设备能和其他设备进行联动
- 设备必须要具备两种能力:(也就是 send 和 recv 的能力)
- 告诉其他设备自己的情况的能力
- 知道其他设备情况的能力(不一定需要)
0.2. 物联网和互联网有什么区别?
- 互联网接入的一般是服务器主机、PC电脑、手机等设备(计算能力强,使用环境较固定)
- 物联网设备可能是摄像头、传感器、门铃门锁等(计算能力弱,网络环境不稳定)
- 互联网设备不论是计算能力还是联网能力都比物联网设备要强
0.3. 物联网协议的就是要符合物联网设备的特点
- 设备性能弱,计算能力有限
联网能力也弱,网络带宽低,信号不稳定
要求:协议不能太复杂,越简单越好
设备数量多,而且交互非常复杂,通常不同设备之间需要有联动
要求:设备与设备之间不能只有C/S 模式,最好能支持:发布—订阅模式
0.4. 为什么要发布订阅?
这种结构有什么好处?好像还更复杂了,多转了一道
当接入的 Client 数量增加时:
Broker:经纪人、中间商、代理
当订阅者数量多的时候,每增加一个订阅者(发布者),对发布者(订阅者)没有任何影响,实现了解耦!
发布订阅的特点:
- 发布者负责生产数据。发布者发送某个主题的数据给经纪人,发布者不知道订阅者。
- 订阅者订阅经纪人管理的某个或者某几个主题。
- 当经纪人接收到某个主题的数据时,将数据发送给这个主题的所有订阅者
现实例子:点外卖找商家 vs 点外卖找美团
另外,由于发布 - 订阅模式减少了发布者与订阅者之间的耦合度,所以网络不稳定导致的临时离线就不会影响彼此的工作。在物联网场景中,一个传感器数据需要触发多个服务或者终端执行动作。
0.5. 互联网协议
今天要介绍的互联网协议都处在 5 层网络模型中的应用层。
1. MQTT 协议
1.1. MQTT 由来
MQTT协议(Message Queue Telemetry Transport,消息队列遥测传输协议)是IBM于1999年为了一个通过卫星网络连接输油管道的项目开发的。为了满足低电量消耗和低网络带宽的需求,MQTT协议在设计之初就包含了以下几个特点。
- 实现简单;
- 提供数据传输的QoS;
- 轻量、占用带宽低;
- 可传输任意类型的数据;
- 可保持的会话(Session)。
1.2. MQTT 协议的通信模型
一次典型的MQTT协议消息通信流程如下图所示:
为了实现不同网络环境的 MQTT Client 能找到 MQTT Broker,一般情况下 MQTT Broker 会放在公网下。
1.3. MQTT 协议格式
所有的MQTT 消息都由这三部分组成:固定头 + 可变头 + 消息体
1.3.1. 固定头
(1)数据类型
MQTT 3.1.1 版本一共定义了 14 种数据包的类型:
(2)数据包标识位
(3)数据包剩余长度
一般情况下固定头只有 2 字节(如果后面内容比较多,固定头最多可以有 5 字节,后面 4 字节都是长度)
所以,4个字节最多可以标识的包长度为:(0xFF,0xFF,0xFF,0x7F)=268 435 455 字节,即 256 MB,这是 MQTT协议中数据包的最大长度
1.3.2. 可变头
1.3.3. 消息体
不同数据类型,消息体不同,详细内容可以参考相关协议文档!
1.4 常的 MQTT 数据类型
- CONNECT(连接)
- SUBSCRIBE(订阅)
- UNSUBSCRIBE(取消订阅)
- PUBLISH(发布)
1.5 QoS
- QoS0:At most once,至多一次。
- QoS1:At least once,至少一次。(可以有多次)
- QoS2:Exactly once,确保只有一次
QoS是消息的发送方(Sender)和接收方(Receiver)之间达成的一个协议。
注意:QoS 是 Sender 和 Receiver 之间达成的协议,不是 Publisher 和 Subscribe 之间达成的协议。也就是说,Publisher 发布一条 QoS1 的消息,只能保证 Broker 至少收到一次;而对应的 Subscriber 能否至少收到一次这个消息,还要取决于 Subscriber 在 Subscribe 的时候和 Broker 协商的 QoS 等级。
问题:为什么要这样交互?
1.6. MQTT 协议总结
面临问题:
- 在物联网应用场景中,IoT 设备性能差,网络连接不稳定。
- 服务端面临的挑战主要是,需要支撑海量的客户端和主题。(可以思考一下服务端也如何部署?)
协议特点:
- 采用二进制的消息内容编码格式,所以二进制数据、JSON 和图片等负载内容都可以方便传输。
- 协议头很紧凑,协议交互也简单,保证了网络传输流量很小。
- 支持 3 种 QoS(Quality of Service,服务质量)级别,便于应用根据不同的场景需求灵活选择。
1.7. MQTT 协议能适用所有的互联网设备吗?
如何设备运行 MQTT 协议时,资源很紧张,发布消息很慢;我的传感器只是发布数据,也要跑 MQTT 协议吗?
最初,MQTT 协议被设计用于在计算资源和网络资源有限的环境下运行,它在大多数的环境下运行都很稳定,不过 MQTT 协议需要建立一个 TCP 长连接,并需要在固定的时间间隔发送心跳包,对于一些使用电池供电的小型设备而言,能耗还是比较明显的。对于一些采集设备的终端而言,其大部分时间是往上发布数据,建立一个可以用于反控的 TCP 连接,可能也有些多余。
2. CoAP 协议
用一句话来概括 CoAP 协议:CoAP 协议是一个建立在 UDP 协议之上的弱化版的 HTTP 协议。如果设备只需要上传数据,那么完全可以调用服务器的 HTTP 接口。如果运行 HTTP 协议对你的设备来说功耗太大,那么使用CoAP 协议就可以解决这个问题。
与 MQTT 协议的 Client-Broker-Client 模型不同,CoAP 协议和 Web 都是 C/S 架构的,设备是 Client,接收设备、发送数据的就是 Server。设备可以通过类似于 coap://192.168.1.150:5683/2ndfloor/temperature 的 URL 来标识一个实体,并使用类似于 HTTP 的 PUT、GET、POST、DELET 请求指令来获取或者修改这个实体的状态。
所以 CoAP(Constrained Application Protocol)协议是一种运行在资源比较紧张的设备上的协议。CoAP 协议设计得非常小巧,最小的数据包只有 4 个字节。
2.1. CoAP 协议的消息模型
一条 CoAP 协议消息由以下三部分组成。
- 二进制头(Header)
- 消息选项(Options)
- 负载(Payload)
CoAP 协议的消息设计得非常紧凑,消息的最小长度为 4 个字节,每个消息都有一个唯一的 ID,便于消息的追踪和去重。
【Ver】 版本编号:指示 CoAP 协议的版本号。类似于 HTTP 1.0 HTTP 1.1。版本编号占 2 位,取值为 01B。
【T】报文类型:CoAP 协议定了 4 种不同形式的报文,CON 报文,NON 报文,ACK 报文和 RST 报文。
【TKL】CoAP 标识符长度:CoAP 协议中具有两种功能相似的标识符,一种为 Message ID (报文编号),一种为 Token (标识符)。其中每个报文均包含消息编号,但是标识符对于报文来说是非必须的。
【Code】功能码/响应码:Code 在 CoAP 请求报文和响应报文中具有不同的表现形式,Code 占一个字节,它被分成了两部分,前 3 位一部分,后 5 位一部分,为了方便描述它被写成了 c.dd 结构。其中 0.XX 表示 CoAP 请求的某种方法,而 2.XX、4.XX 或 5.XX 则表示 CoAP 响应的某种具体表现。
【Message ID】报文编号
【Token】标识符具体内容,通过 TKL 指定 Token 长度。
【Option】报文选项,通过报文选项可设定 CoAP 主机,CoAP URI,CoAP 请求参数和负载媒体类型等等。
【1111 1111】CoAP 报文和具体负载之间的分隔符。
CoAP协议的消息可分为两种:
- 一种是需要被确认的消息CON(Confirmable message)
- 一种是不需要确认的消息NON(Non-confirmable message)
2.2 CON
CON 是一种可靠消息,当接受方收到CON消息时,需要回复发送方,如果发送方没有收到接受方的回复,则不停地重新发送消息。
Server 正常处理完 CON 消息时,应该向 Client 回复 ACK,ACK 中包含了与 CON 消息一样的 ID
如果Server无法处理Client的CON消息,Server可以向Client回复RST消息,Client收到RST消息之后,将不再等待ACK
2.3. NON
NON是一种不可靠消息,这种消息不需要接收方的回复。
2.4. CoAP 的请求应答机制
CoAP 协议的请求/应答是建立在前面讲到的 CON 和 NON 的基础上的,CoAP 协议的请求和 HTTP 协议的请求非常相似,其包含 GET、POST、PUT、DELETE 4 种方法和请求的 URL。
Token 的作用是匹配请求和应答。如果 Server 没有办法在收到 Client 请求时立刻给 Client 应答,它可以先回复一个空的 ACK 消息,当 Server 准备好对 Client 进行应答时,再向 Client 发送一个包含同样 Token 字段的 CON消息,这类似于一种异步应答机制
2.5. CoAP OBSERVER
CoAP提供一种观察模式,观察者可以通过 OBSERVE 指令向 CoAP 服务器指明观察的实体对象。当实体对象的状态发生变化时,观察者就可以收到实体对象的最新状态,类似于 MQTT 协议中的订阅功能。
CoAP 的通信模型如下:
在NAT转换后,尤其是在3G/4G的网络下,从Server到Client的UDP传输是很不可靠的,所以不建议单纯用CoAP协议做数据收集之外的事情,比如设备控制等。
2.6. CoAP HTTP 网关
由于 CoAP 协议和 HTTP 协议有很大的相似性,因此通常可以用一个 Gateway 将 CoAP 协议转换成 HTTP 协议,便于接入已有的基于 Web 的系统
2.7. CoAP 总结
一般来说,CoAP 协议比较适合:性能差、同时只有单向传输需求的设备,一般只实现上行数据的功能。
CoAP 协议简单,传输层使用 UDP,由于与 HTTP 类似,上手比较简单。而且也可以通过网关接入 web 系统。
CoAP 消息有 2 种,需要确认消息的消息和不需要确认的消息。
3. DDS 协议
数据分发服务(DDS) 是用于分布式软件应用通信的以数据为中心的通信协议。(准确来说 DDS 是一种网络中间件,并不是一个应用层协议)
3.1. 全局数据空间
- 首先全局数据空间是一个抽象的概念,并不是说有一个服务器或者主机来保存所有的数据。
- DDS以数据为中心,也就是基于数据去考虑如何分发消息。因此在DDS中存在全局数据空间的概念。这个全局数据空间是虚拟(逻辑)上的,所有数据都在这个空间中,每个分布式结点可以向这个空间写数据,也可以从这个空间读数据。
- DDS 建立在全局数据空间的概念之上。中间件负责在发布者和订阅者之间传播信息。
- 逻辑上统一,物理上分布式的。
3.2. DCPS 概念模型
DCPS(Data-Centric Publish-Subscribe)是 DDS 标准中定义的以数据为中心的订阅-发布模型。
在这个模型中,向“全局数据空间“写入数据的一方称为 Publishers 和 DataWriter,同样地,在”全局数据空间“中读取数据的一方称为 Subscriber 和 DataReader,下图中展示了它们之间的逻辑关系。
除了 DCPS 模型,DDS 标准中还定义了一套完整的应用程序接口(API),该接口标准是与平台无关的,这意味着不论应用程序使用什么开发语言,或运行在什么平台之上,只要 DDS 中间件的实现符合 DDS 标准,那么相关的应用程序即可实现不同平台间的移植。
- 域。标识 DDS 域的正整数。每个 DomainParticipant 都会有一个分配的DDS 域,这样同一个域中的DomainParticipant 就可以进行通信,也可以隔离DDS 域之间的通信。该值必须由应用程序开发人员在创建 DomainParticipants 时提供。
- 域参与者。包含其他 DDS 实体(例如发布者、订阅者、主题和多主题)的对象。
- 主题。将发布者的 DataWriter 与订阅者的 DataReader 绑定的实体。
- 发布者。发布者使用 DataWriter 发布主题下的数据。它是创建和配置 DataWriter 的实体,并且可能包含其中一个或多个。
- 数据写入器。它是负责发布消息的实体。用户在创建此实体时必须提供一个主题,该主题将是发布数据的主题。发布是通过将数据对象写入 DataWriterHistory 中的更改来完成的。
- 数据写入器历史记录。这是对数据对象的更改列表。当 DataWriter 继续在特定主题下发布数据时,它实际上会在此数据中创建更改。记录在历史记录中的正是这种变化。然后将这些更改发送到订阅该特定主题的 DataReader。
- 订阅者。订阅者使用 DataReader 订阅主题,后者从传输中读取数据。它是创建和配置它包含的 DataReader 实体的实体,并且可能包含一个或多个 DataReader 实体。
- 数据读取器。它是订阅主题以接收发布的实体。创建此实体时,用户必须提供订阅主题。DataReader 接收消息作为其 HistoryDataReader 中的更改。
- 数据读取器历史记录。它包含DataReader 由于订阅某个主题而接收到的数据对象的变化。
3.3. RTPS 模型概念
3.3.1. P/S
订阅/发布,从通信角度考虑。其实,就是 P/S 通信模式。P(Publish)是发布者,S(Subscribe)是订阅者,订阅者订阅发布者提供的某些服务后,P 与 S 间就存在了通信关系。发布者发布了相应的消息后,订阅者便可以收到这些消息(数据)。
3.3.2. RTPS
Real Time Publish/Subscribe,它继承自 P/S 模型。简单来说,相比 P/S,RTPS 多出了 QoS 属性(Quality of Service)、将发布/订阅模块化等等优点。
- RTPS 域。它是 DDS 域对 RTPS 协议的扩展。
- RTPS 参与者。包含其他 RTPS 实体。它允许配置和创建它包含的实体。
- RTPSWriter。消息的来源。它读取写入 DataWriterHistory 中的更改并将它们传输到它之前匹配的所有 RTPSReader。
- RTPSReader。消息的接收实体。它将 RTPSWriter 中的更改写入 DataReaderHistory。
3.4. 总架构图
OMG 将 RTPS 标准化为:DDS 的实施互操作协议
3.5. DDS 实体的层次结构
DDS 是完全分布式的,没有中心节点,任何两个节点之间都是直接通信的,示意图如下:
为了实现这样的系统,首先要解决的是各节点的互相发现问题。DDS 本身并没有定义应该如何发现各节点,而是在 RTPS 中定义该行为。RTPS(Real-time Publish-Subscribe Protocol) 用来支撑 DDS 的实现,是 DDS 底层使用的协议,用来保证各种 DDS 的实现之间可以互操作。在 RTPS 中定义了两个独立的发现协议,分别是 PDP(Participant Discovery Protocol) 和 EDP(Endpoint Discovery Protocol),PDP 用于发现各参与节点,EDP 用于发现每个节点提供的所有端点(Endpoints)。PDP 的实现可以通过单播列表或者组播实现。RTPS 允许实现者实现不同的 PDP 和 EDP 协议,但是至少要实现 SPDP(Simple PDP) 和 SEDP(Simple EDP) 协议。
3.6. DDS 发现
简单发现:这是默认机制。它支持 PDP 和 EDP 的 RTPS 标准,因此提供与任何其他 DDS 和 RTPS 实现的兼容性。
静态发现:当所有数据写入器和数据读取器的 IP 和端口、数据类型和主题是事先知道的。(直接内置 IP 和端口到xml文件中)
手动发现:此机制仅与 RTPS 层兼容。
发现服务器:此发现机制使用集中式发现架构,其中称为服务器的域参与者充当发现元流量的中心。服务器可以充当其他服务器的客户端
DDS 性能调研
DDS 总结
- 以数据为中心,数据吞吐量大,数据传输实时性好(去中心化)
- 采用全局数据空间技术,大大地提高通信效率
- 引入服务质量策略(QoS),增加了通信灵活性
- 对设备性格要求较高,网络环境要求也高
- 订阅的设备有数量限制,不适合海量订阅传输的场景
参考:
Fast RTPS原理与代码分析(2):动态发现协议之参与者发现协议PDP
DDS基本原理研究
数据分发服务DDS技术研究
DDS(Data Distribution Service) 中间件
物联网协议对比(HTTP、websocket、XMPP、COAP、MQTT和DDS协议)
MQTT 协议简介、与Websocket的区别