MQTT协议的消息格式是其设计中的核心部分。理解消息的结构对于正确实现和使用MQTT协议至关重要。下面我们详细讲解MQTT消息的各个组成部分,包括固定头、变量头和有效载荷。
1 消息的基本组成
MQTT消息主要由以下几个部分组成:
- 固定头(Fixed Header):消息的固定部分,包含消息类型、标志位、剩余长度等信息。
- 变量头(Variable Header):消息的可选部分,包含与消息相关的元数据,如主题名称、消息ID等。
- 有效载荷(Payload):消息的实际内容,包含具体的数据。
2 固定头(Fixed Header)
2.1 固定头结构
固定头的结构如下:
+-----------------+
| 消息类型 | 保留标志 | QoS等级 | 保留标志 | 消息剩余长度 |
+-----------------+
- 消息类型(Message Type):一个字节,标识消息的类型,如
CONNECT
、PUBLISH
等。 - 保留标志(Reserved):一个位,保留字段,通常设置为0。
- QoS等级(Quality of Service):两个位,指定消息的传递服务质量等级,取值为0、1、2。
- 剩余长度(Remaining Length):一个可变长度的字段,指定消息的剩余部分的长度,支持0到268,435,455字节。
2.2 消息类型定义
MQTT消息类型定义如下:
消息类型 | 二进制值 | 描述 |
---|---|---|
CONNECT | 1 | 客户端连接请求 |
CONNACK | 2 | 连接确认 |
PUBLISH | 3 | 发布消息 |
PUBACK | 4 | 发布确认 |
PUBREC | 5 | 发布接收 |
PUBREL | 6 | 发布释放 |
PUBCOMP | 7 | 发布完成 |
SUBSCRIBE | 8 | 订阅请求 |
SUBACK | 9 | 订阅确认 |
UNSUBSCRIBE | 10 | 取消订阅请求 |
UNSUBACK | 11 | 取消订阅确认 |
PINGREQ | 12 | 心跳请求 |
PINGRESP | 13 | 心跳响应 |
DISCONNECT | 14 | 客户端断开连接请求 |
3 变量头(Variable Header)
变量头包含与消息相关的元数据,具体结构和内容依消息类型而异。
1 CONNECT消息的变量头
CONNECT消息的变量头包括以下字段:
- 协议名称(Protocol Name):一个字符串,通常为“MQTT”。
- 协议版本(Protocol Level):一个字节,表示协议的版本号,当前版本为4。
- 连接标志(Flags):一个字节,包含连接标志,如用户名、密码、保留会话等。
- 保持会话时间(Keep Alive):两个字节,指定客户端和代理之间的最大空闲时间,单位为秒。
+-------------------------------+
| 协议名称长度(2字节) |
| 协议名称(MQTT,字符串) |
+-------------------------------+
| 协议版本(1字节) |
+-------------------------------+
| 连接标志(1字节) |
+-------------------------------+
| 保持会话时间(2字节) |
+-------------------------------+
2 PUBLISH消息的变量头
PUBLISH消息的变量头包括以下字段:
- 主题名称长度(Topic Name Length):两个字节,表示主题名称的长度。
- 主题名称(Topic Name):一个字符串,表示消息的主题名称。
- 消息ID(Message ID):对于QoS等级1和2,包含一个2字节的消息ID,用于跟踪消息的传输状态。
+-------------------------------+
| 主题名称长度(2字节) |
+-------------------------------+
| 主题名称(字符串) |
+-------------------------------+
| 消息ID(2字节,QoS1和2) |
+-------------------------------+
3 SUBSCRIBE消息的变量头
SUBSCRIBE消息的变量头包括以下字段:
- 消息ID(Message ID):两个字节,标识订阅请求的唯一标识符。
+-------------------------------+
| 消息ID(2字节) |
+-------------------------------+
4 有效载荷(Payload)
有效载荷是消息的实际内容,具体内容根据消息类型的不同而有所变化。
4.1 CONNECT消息的有效载荷
CONNECT消息的有效载荷包括以下字段:
- 客户端ID(Client ID):一个字符串,标识客户端的唯一身份。
- 用户名(Username):可选字段,表示客户端的用户名。
- 密码(Password):可选字段,表示客户端的密码。
+-------------------------------+
| 客户端ID长度(2字节) |
+-------------------------------+
| 客户端ID(字符串) |
+-------------------------------+
| 用户名长度(可选,2字节) |
+-------------------------------+
| 用户名(可选,字符串) |
+-------------------------------+
| 密码长度(可选,2字节) |
+-------------------------------+
| 密码(可选,字符串) |
+-------------------------------+
4.2 PUBLISH消息的有效载荷
PUBLISH消息的有效载荷是消息的实际内容,格式为字符串或二进制数据,具体内容由应用层协议定义。
+-------------------------------+
| 消息内容(字符串或二进制) |
+-------------------------------+
4.3 SUBSCRIBE消息的有效载荷
SUBSCRIBE消息的有效载荷包括多个订阅主题和QoS等级,格式如下:
+-------------------------------+
| 主题长度(2字节) |
+-------------------------------+
| 主题(字符串) |
+-------------------------------+
| QoS等级(1字节) |
+-------------------------------+