LV02-01-天猫精灵IOT-04-MQTT协议-01-基本概念
本文主要是天猫精灵IOT MQTT协议——基本概念的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
Windows版本 | windows11 |
Ubuntu版本 | Ubuntu22.04的64位版本 |
VMware® Workstation 16 Pro | 16.2.3 build-19376536 |
终端软件 | MobaXterm(Professional Edition v23.0 Build 5042 (license)) |
点击查看本文参考资料
分类 | 网址 | 说明 |
官方网站 | 阿里云 | 阿里云官网主页 |
阿里生活物联平台 | 生活物联网平台(飞燕平台)主页 | |
AliGenie | 天猫精灵开放平台AliGenie主页 | |
阿里物联网平台 | 阿里物联网平台主页 | |
Bluetooth 技术网站 | 蓝牙协议规范什么的可以来这里找 | |
Telink | Telink | Chips for a Smarter IoT (telink-semi.com) Telink中文官网 | |
开发手册 | AliOS Things开发指南 | AliOS Things开发指南,这里是最新版本,可以直接从官网找到 |
AliOS Things开发指南 | AliOS Things应用开发指南,这里应该是3.3版本的完整开发文档 | |
AliOS Things开发指南(3.0) | AliOS Things应用开发指南,这里应该是3.0版本的完整开发文档 | |
生活物联网平台开发文档 | 生活物联网平台(飞燕平台)开发文档 《设备端开发指南》 | |
Wi-Fi IoT品类定义与功能开发 | 天猫精灵IoT开放平台——Wi-Fi IoT品类定义与功能开发 | |
硬件平台 | mk3080 WiFi开发板 | WiFi开发板使用指南-阿里云开发者社区 |
esp8266开发板 | 一个教程:ESP8266-NodeMCU开发板详解-太极创客 (taichi-maker.com) | |
TLSR8258 Datasheet | Datasheet for Telink BLE + IEEE802.15.4 MultiStandard Wireless SoC TLSR8258 | |
参考资料 | AliOS Things 3.0 应用开发指南 | 这个只是一篇参考文章,里面是一些环境搭建相关的,可以参考 |
IP知识百科 - 华为 (huawei.com) | IP的一些相关知识点 |
点击查看相关文件下载
分类 | 网址 | 说明 |
蓝牙规范相关文档 | Core Specification 5.2 | 核心规格 5.2,该规范定义了创建可互操作的Bluetooth 设备所需的技术。 《Core_v5.2.pdf》 |
Mesh Model(v1.1) | 本Bluetooth 规范定义了模型(以及它们所需的状态和消息),这些模型用于在mesh 网络中的节点上执行基本功能,超出了Bluetooth Mesh 配置文件 规范中定义的基础模型。 本规范包括定义跨设备类型标准功能的通用模型,以及支持关键mesh 场景的模型,如照明控制、传感器、时间和场景。 《MshMDL_v1.1.pdf》 | |
Mesh Profile(v1.0.1) | 该Bluetooth 规范定义了基本要求,以实现可互操作的mesh 网络解决方案,用于Bluetooth 低能量无线技术。 《MshPRFv1.0.1.pdf》 | |
Mesh Device Properties | 本规范包含Bluetooth Mesh 配置文件 和Bluetooth Mesh 模型规范所要求的设备属性的定义。 但是跟之前的有些区别,我主要看的之前的版本:《MMeshDeviceProperties_v1.2.pdf》 | |
GATT Specification Supplement | GATT Specification Supplement | Bluetooth® Technology Website。 好像可以在线看:《GATT Specification Supplement》 | |
Assigned Numbers | GATT的一些类型定义可以在这里找。 | |
AliOS Things | alios-things/AliOS-Things | Gitee上的AliOSThings SDK源码仓库 |
alibaba/AliOS-Things | GitHub上的AliOSThings SDK源码仓库 | |
天猫精灵蓝牙Mesh协议栈 | alibaba-archive/genie-bt-mesh-stack | GitHub上的天猫精灵蓝牙Mesh协议栈源码仓库。 之前是在alibaba/genie-bt-mesh-stack这个仓库。 写笔记的时候最新提交为faf523618a6a2560090fc423222b9db80984bb7a |
蓝牙Mesh设备开发指南 | 阿里云生活服务平台开发手册——蓝牙设备开发一节中的内容 |
一、MQTT简介
1. 什么是MQTT?
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,用极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
MQTT协议当前版本为,2014年发布的MQTT v3.1.1。除标准版外,还有一个简化版MQTT-SN
,该协议主要针对嵌入式设备,这些设备一般工作于TCP/IP网络,如:ZigBee。MQTT 与 HTTP 一样,MQTT 运行在传输控制协议/互联网协议 (TCP/IP) 之上,属于一个应用层协议。
2. 官网
MQTT协议的官网在这里:MQTT - The Standard for IoT Messaging,官网有着对MQTT协议最详细的解释。
3. 为什么要有MQTT协议?
大多数开发人员已经熟悉 HTTP Web 服务。那么为什么不让 IoT 设备连接到 Web 服务?设备可采用 HTTP 请求的形式发送其数据,并采用 HTTP 响应的形式从系统接收更新。这种请求和响应模式存在一些严重的局限性:
(1)HTTP 是一种同步协议。客户端需要等待服务器响应。Web 浏览器具有这样的要求,但它的代价是牺牲了可伸缩性。在 IoT 领域,大量设备以及很可能不可靠或高延迟的网络使得同步通信成为问题。异步消息协议更适合 IoT 应用程序。传感器发送读数,让网络确定将其传送到目标设备和服务的最佳路线和时间。
(2)HTTP 是单向的。客户端必须发起连接。在 IoT 应用程序中,设备或传感器通常是客户端,这意味着它们无法被动地接收来自网络的命令。HTTP 是一种 1-1 协议。客户端发出请求,服务器进行响应。将消息传送到网络上的所有设备上,不但很困难,而且成本很高,而这是 IoT 应用程序中的一种常见使用情况。
(3)HTTP 是一种有许多标头和规则的重量级协议。它不适合受限的网络。
4. MQTT协议特点
4.1 优势
精简,不添加可有可无的功能;
发布/订阅(Pub/Sub)模式,方便消息在传感器之间传递;
允许用户动态创建主题,零运维成本;
把传输量降到最低以提高传输效率;
把低带宽、高延迟、不稳定的网络等因素考虑在内;
支持连续的会话控制;
理解客户端计算能力可能很低;
提供服务质量管理;
假设数据不可知,不强求传输数据的类型与格式,保持灵活性。
4.2 劣势
- 可扩展性有限
MQTT协议的可扩展性有限,不适合大规模的物联网应用。
- 不支持请求/响应模式
MQTT协议不支持请求/响应模式,限制了一些应用场景。
- 不支持消息队列
MQTT协议不支持消息队列,限制了一些应用场景。
- 消息传递的延迟
由于MQTT协议的发布/订阅模式,消息传递的延迟可能会比较大,不适合实时性要求较高的应用场景。
5. MQTT的应用领域有哪些?
- 传感器数据的采集和传输
许多传感器需要将采集的数据传输到服务器或其他设备中进行处理,MQTT协议可以实现数据的实时传输和管理。
- 智能家居
MQTT协议可以用于智能家居中各种设备之间的通信和控制,例如智能灯光、智能家电、智能安防等。
- 智能交通
MQTT协议可以用于智能交通系统中各个设备之间的通信和协作,例如智能导航、智能停车、智能交通灯等。
- 智能制造
MQTT协议可以用于智能制造中各种设备之间的通信和控制,例如智能生产线、智能仓储等。
- 物流和供应链
MQTT协议可以用于物流和供应链中各个环节之间的通信和协作,例如智能仓储、智能物流等。
- 能源管理
MQTT协议可以用于能源管理中各种设备之间的通信和控制,例如智能电网、智能能源监测等。
- 智慧城市
MQTT协议可以用于智慧城市的建设和管理中,例如智能路灯、智能公交、智能城市管理等。
二、MQTT基本原理
1. 几个基本概念
MQTT
使用的发布/订阅消息模式,它提供了一对多的消息分发机制,从而实现与应用程序的解耦。这是一种消息传递模式,消息不是直接从发送器发送到接收器(即点对点),而是由MQTT server
(或称为 MQTT Broker)分发的。
MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。
2. 基本原理
MQTT的基本原理是发布/订阅模式。在MQTT中,消息发布者(Publisher)将消息发布到一个主题(Topic)上,而消息订阅者(Subscriber)则订阅这个主题,当有新的消息发布到这个主题上时,订阅者将会收到这个消息。MQTT的消息传递过程如下:
- 发布者将消息发送到MQTT Broker(代理服务器)上,并指定消息发布的主题。
- 订阅者通过订阅相应的主题,向MQTT Broker注册对该主题的订阅。
- 当有新的消息发布到该主题时,MQTT Broker会将消息发送给所有订阅了该主题的订阅者。
MQTT协议使用TCP/IP协议栈进行通信,因此在使用MQTT协议时需要建立TCP连接。MQTT协议支持三种不同的服务质量级别(QoS级别),可以根据需求选择适当的级别。当消息发布者发布消息时,可以指定消息的QoS级别,用于保证消息的可靠性和传递的顺序。
MQTT协议还支持保留消息(Retained Messages)和遗嘱消息(Last Will and Testament)。保留消息是指最新的消息将一直保存在服务器上,新的订阅者可以获取最新的消息。遗嘱消息是指在客户端异常断开连接时自动发送一条消息,用于通知其他订阅者该客户端已经离线。
三、MQTT的QoS
1. 什么是QoS
MQTT设计了一套保证消息稳定传输的机制,包括消息应答、存储和重传。在这套机制下,提供了三种不同层次QoS(Quality of Service):
- QoS0,At most once,“最多一次”,消息发布完全依赖底层 TCP/IP 网络。分发的消息可能丢失或重复。例如,这个等级可用于环境传感器数据,单次的数据丢失没关系,因为不久后还会有第二次发送。
- QoS1,At least once,“至少一次”,确保消息可以到达,但消息可能会重复。
- QoS2,Exactly once,“只有一次”,确保消息只到达一次。例如,这个等级可用在一个计费系统中,这里如果消息重复或丢失会导致不正确的收费。
QoS是Sender和Receiver之间的协议,而不是Publisher和Subscriber之间的协议。换句话说,Publisher发布了一条QoS1的消息,只能保证Broker能至少收到一次这个消息;而对于Subscriber能否至少收到一次这个消息,还要取决于Subscriber在Subscibe的时候和Broker协商的QoS等级。
2. 三种QoS说明
2.1 QoS0
QoS0 代表,Sender 发送的一条消息,Receiver 最多能收到一次,也就是说 Sender 尽力向 Receiver 发送消息,如果发送失败,也就算了。
QoS0等级下,Sender和Receiver之间一次消息的传递流程如下:
Sender向Receiver发送一个包含消息数据的PUBLISH包,然后不管结果如何,丢掉已发送的PUBLISH包,一条消息的发送完成。
2.2 QoS1
QoS1要保证消息至少到达一次,所以有一个应答的机制。Sender和Receiver的一次消息的传递流程如下:
(1)Sender向Receiver发送一个带有数据的PUBLISH包,并在本地保存这个PUBLISH包;
(2)Receiver收到PUBLISH包以后,向Sender发送一个PUBACK数据包,PUBACK数据包没有消息体(Payload),在可变头中有一个包标识(Packet Identifier),和它收到的PUBLISH包中的Packet Identifier一致。
(3)Sender收到PUBACK之后,根据PUBACK包中的Packet Identifier找到本地保存的PUBLISH包,然后丢弃掉,一次消息的发送完成。
但是消息传递流程中可能会出现问题:
- 如果Sender在一段时间内没有收到PUBLISH包对应的PUBACK,它将该PUBLISH包的DUP标识设为1(代表是重新发送的PUBLISH包),然后重新发送该PUBLISH包。
- Receiver可能会重复收到消息,需自行去重。
2.3 QoS2
相比QoS0和QoS1,QoS2不仅要确保Receiver能收到Sender发送的消息,还需要确保消息不重复。它的重传和应答机制就要复杂一些,同时开销也是最大的。QoS2下,一次消息的传递流程如下所示:
(1)Sender发送QoS为2的PUBLISH数据包,数据包 Packet Identifier 为 P,并在本地保存该PUBLISH包;
(2)Receiver收到PUBLISH数据包后,在本地保存PUBLISH包的Packet Identifier P,并回复Sender一个PUBREC数据包,PUBREC数据包可变头中的Packet Identifier为P,没有消息体(Payload);
(3)当Sender收到PUBREC,它就可以安全的丢弃掉初始Packet Identifier为P的PUBLISH数据包。同时保存该PUBREC数据包,并回复Receiver一个PUBREL数据包,PUBREL数据包可变头中的Packet Identifier为P,没有消息体;
(4)当Receiver收到PUBREL数据包,它可以丢掉保存的PUBLISH包的Packet Identifier P,并回复Sender一个可变头中 Packet Identifier 为 P,没有消息体(Payload)的PUBCOMP数据包;
(5)当Sender收到PUBCOMP包,那么认为传输已完成,则丢掉对应的PUBREC数据包。
上面是一次完整无误的传输过程,然而传输过程中可能会出现以下情况:
- 情况1:Sender发送PUBLISH数据包给Receiver的时候,发送失败;
- 情况2:Sender已经成功发送PUBLISH数据包给Receiver了,但是Receiver发送PUBREC数据包失败;
- 情况3:Sender已经成功收到了PUBREC数据包,但是PUBREL数据包发送失败;
- 情况4:Receiver已经收到了PUBREL数据包,但是发送PUBCOMP数据包时发送失败
针对上述的问题,较为详细的处理方法如下:
- 不管是情况1还是情况2,因为Sender在一定时间内没有收到PUBREC,那么它会把PUBLISH包的DUP标识设为1,重新发送该PUBLISH数据包;
- 不管是情况3还是情况4,因为Sender在一定时间内没有收到PUBCOMP包,那么它会重新发送PUBREL数据包;
- 针对情况2,Receiver可能会收到多个重复的PUBLISH包,更加完善的处理如下:
Receiver在收到PUBLISH数据包之后,马上回复一个PUBREC数据包。并会在本地保存PUBLISH包的Packet Identifier P,不管之后因为重传多少次这个Packet Identifier 为P的数据包,Receiver都认为是重复的,丢弃。同时Receiver接收到QoS为2的PUBLISH数据包后,并不马上投递给上层,而是在本地做持久化,将消息保存起来(这里需要是持久化而不是保存在内存)。- 针对情况4,更加完善的处理是:Receiver收到PUBREL数据包后,正式将消息递交给上层应用层,投递之后销毁Packet Identifier P,并发送PUBCOMP数据包,销毁之前的持久化消息。之后不管接收到多少个PUBREL数据包,因为没有Packet Identifier P,直接回复PUBCOMP数据包即可。
3. QoS等级使用建议
在以下情况下可以选择 QoS0:
- Client 和 Broker 之间的网络连接非常稳定,例如一个通过有线网络连接到 Broker 的测试用 Client;
- 我们可以接受丢失部分消息,比如我们有一个传感器以非常短的间隔发布状态数据,所以丢一些也可以接受;
- 我们不需要离线消息。
在以下情况下应该选择 QoS1:
- 我们需要接收所有的消息,而且我们的应用可以接受并处理重复的消息;
- 我们无法接受 QoS2 带来的额外开销,QoS1 发送消息的速度比 QoS2 快很多。
在以下情况下应该选择 QoS2:
- 我们的应用必须接收到所有的消息,而且应用在重复的消息下无法正常工作,同时我们也能接受 QoS2 带来的额外开销。
4. 实际QoS级别
MQTT 协议中,从 Broker 到 Subscriber 这段消息传递的实际 QoS 等于:Publisher 发布消息时指定的 QoS 等级和 Subscriber 在订阅时与 Broker 协商的 QoS 等级,这两个 QoS 等级中的最小那一个。
Actual Subscribe QoS = MIN(Publish QoS, Subscribe QoS)
四、MQTT的消息
1. 消息组成
MQTT 传输的消息分为:主题(Topic)和 负载/载荷(payload)两部分:
Topic:消息的类型/主题,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload)。
payload:消息的内容,指订阅者需要的具体内容。
2. 消息类型
CONNECT —— 连接服务端
CONNACK —— 确认连接请求
PUBLISH —— 发布消息
PUBACK —— 发布确认(QOS1)
PUBREC —— 发布收到 (QOS2)
PUBREL —— 发布释放(QOS2)
PUBCOMP —— 发布完成(QOS2)
SUBSCRIBE —— 订阅主题
SUBACK —— 订阅确认
UNSUBSCRIBE —— 取消订阅
UNSUBACK —— 取消订阅确认
PINGREQ —— 心跳请求
PINGRESP —— 心跳响应
DISCONNECT —— 断开连接
五、报文格式
1. 一般格式
一般格式如下:
Fixed header | 固定报头,所有的控制报文都有 |
Variable header | 可变报头,部分控制报文包含 |
Payload | 有效载荷,部分控制报文包含 |
2. 固定头部说明
byte 1的[7:4]这四个位表示报文的类型:
byte 2的[7:0]是保留长度: