MQTT与MQTT-SN协议详解
立即解锁
发布时间: 2025-08-30 02:06:45 阅读量: 8 订阅数: 13 AIGC 

# 深入解析MQTT及MQTT - SN协议:架构、特性与实践
## 1. MQTT协议概述
MQTT是一种广泛应用于物联网(IoT)的消息传输协议,云管理的MQTT代理通常每小时可以处理数百万条消息,并支持数万个发布者。
### 1.1 数据格式与有效负载
MQTT对数据格式没有严格要求,有效负载可以是文本消息、图像数据、音频数据、加密数据、二进制数据、JSON对象等。不过,JSON文本和二进制数据是最常见的有效负载类型。MQTT允许的最大数据包大小为256 MB,但实际的最大数据有效负载大小取决于云服务提供商和代理。例如,IBM Watson允许的有效负载大小最大为128 KB,而Google支持256 KB。此外,发布的消息可以包含零长度的有效负载,因为有效负载字段是可选的。在使用时,建议与云服务提供商确认有效负载大小,以避免错误和断开连接。
### 1.2 架构细节
- **名称误解**:MQTT这个名称容易让人误解,实际上该协议本身并没有消息队列。虽然可以对消息进行排队,但通常并不需要这样做。
- **基于TCP**:MQTT基于TCP协议,因此能保证数据包的可靠传输。
- **非对称协议**:与HTTP的对称协议不同,MQTT是一种非对称协议。在非对称协议中,节点A与节点B通信时,只需要一方(如A)使用该协议,且所有用于数据包重组的信息必须包含在A发送的分段头中。非对称系统通常有一个主节点和一个从节点,如FTP。而对称协议中,双方都需要安装协议,并且可以互换主从角色,如Telnet。MQTT的这种角色区分在传感器/云拓扑中非常适用。
- **消息保留**:MQTT可以在代理上无限期保留消息,这一功能通过普通消息传输中的一个标志来控制。当有新客户端订阅该MQTT主题分支时,代理会立即将保留的消息发送给它,使新客户端无需等待即可获取状态或信号。
### 1.3 遗言机制(Last Will and Testament, LWT)
客户端在连接阶段可以指定LWT消息,其中包含遗言主题、服务质量(QoS)和实际消息。如果客户端异常断开连接(如保活超时、I/O错误或未正常断开会话),代理有义务将LWT消息广播给所有订阅该主题的客户端。
### 1.4 保活机制
尽管MQTT基于TCP,但在无线传感器环境中,连接仍可能丢失。设备可能会断电、信号减弱或崩溃,导致会话进入半开放状态。为了解决这个问题,MQTT使用保活机制。客户端向代理发送PINGREQ数据包,代理用PINGRESP进行响应。客户端和代理都预设了一个定时器,如果在预定时间内没有消息传输,则应发送保活数据包。PINGREQ或消息都会重置保活定时器。如果未收到保活消息且定时器超时,代理将关闭连接并向所有客户端发送LWT数据包。客户端之后可以尝试重新连接,此时代理会关闭半开放连接并建立新连接。保活时间的最大值为18小时12分钟15秒,将保活间隔设置为0将禁用保活功能,且定时器由客户端控制,可以根据睡眠模式或信号强度动态调整。
### 1.5 持久连接
为了减少重新建立客户端订阅和QoS参数时在数据受限连接上产生的不必要开销,MQTT支持持久连接。持久连接会在代理端保存以下信息:
- 客户端的所有订阅
- 客户端未确认的所有QoS消息
- 客户端错过的所有新QoS消息
这些信息通过client_id参数来识别唯一的客户端。客户端可以请求持久连接,但代理可以拒绝请求并强制重新开始一个干净的会话。连接时,代理使用cleanSession标志来允许或拒绝持久连接,客户端可以通过CONNACK消息确定是否保存了持久连接。持久会话适用于需要在离线时接收所有消息的客户端,而对于只向主题发布(写入)数据的客户端则不适用。
### 1.6 服务质量(QoS)
MQTT有三个级别的服务质量:
| QoS级别 | 描述 | 适用场景 |
| ---- | ---- | ---- |
| QoS - 0(非保证传输) | 这是最低的QoS级别,类似于一些无线协议中的“即发即弃”模型,是一种尽力而为的传输过程,接收方无需确认消息,发送方也不会重新尝试传输。 | 不需要消息排队的场景,适用于有线连接或带宽严重受限的系统。 |
| QoS - 1(保证传输) | 该模式保证消息至少会被接收方接收一次,可能会重复传输,接收方会用PUBACK响应进行确认。 | 作为默认使用模式,比QoS - 2快得多,能大大降低传输成本。 |
| QoS - 2(应用层保证服务) | 这是最高的QoS级别,确保并通知发送方和接收方消息已正确传输。该模式通过发送方和接收方之间的多步握手产生更多流量。如果接收方收到QoS - 2的消息,会用PUBREC消息响应发送方,发送方再用PUBREL消息响应,接收方用PUBCOMP确认PUBREL消息。在发送PUBCOMP消息之前,接收方会缓存原始消息以确保安全。 | 适用于关键任务应用,以及重复消息传输可能导致故障的情况。 |
### 1.7 数据包结构
MQTT数据包位于OSI模型网络栈的TCP层之上,由2字节的固定头(必须存在)、可变大小的头(可选)和有效负载(可选)组成。
### 1.8 通信格式
MQTT通信从客户端向代理发送CONNECT消息开始,只有客户端可以发起会话,且客户端之间不能直接通信。代理会用CONNACK响应和状态码回复CONNECT消息,连接建立后保持开放。以下是MQTT的主要消息和格式:
#### 1.8.1 CONNECT格式(客户端到服务器)
| 字段 | 要求 | 描述 |
| ---- | ---- | ---- |
| clientID | 必需 | 向服务器标识客户端,每个客户端有唯一的ID,长度为1到23个UTF - 8字节。 |
| cleanSession | 可选 | 0:服务器必须恢复与客户端的通信,客户端和服务器在断开连接后必须保存会话状态;1:客户端和服务器必须丢弃先前的会话并开始新的会话。 |
| username | 可选 | 服务器用于身份验证的名称。 |
| password | 可选 | 0到65536字节的二进制密码,前面有2字节的长度前缀。 |
| lastWillTopic | 可选 | 发布遗言消息的主题分支。 |
| lastWillQos | 可选 | 2位,指定发布遗言消息时的QoS级别。 |
| lastWillMessage | 可选 | 定义遗言消息的有效负载。 |
| lastWillRetain | 可选 | 指定发布遗言时是否保留。 |
| keepAlive | 可选 | 以秒为单位的时间间隔,客户端负责在保活定时器到期前发送消息或PINGREQ数据包,服务器将在1.5倍保活时间后断开网络连接,值为0将禁用保活机制。 |
#### 1.8.2
0
0
复制全文
相关推荐









