什么是MQTT协议?
MQTT协议是构建与tcp/ip协议的一种应用层协议,我们常见的http就是一种应用层协议。MQTT协议的优点在于可以使用极少的代码和有限的带宽去传输信息,因为其低开销,低带宽占用的及时通讯特点使其在物联网,小型设备直接的通讯等中十分常见。
MQTT协议的格式
每条MQTT的消息都包含一个固定的报头,有些消息会携带一个可变报文头和一个负荷。
固定头
固定头顾名思义就是每个mqtt消息头部都要包含的头部,它最少可为两字节。
字节 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
字节1 | 讯息类型 | DUP标志 | QoS等级 | 保留 | ||||
字节2 | 剩余长度 |
上表为我们展示了固定头的格式。
字节一:
讯息类型占了第一个字节中的第7位到第4位,
助记符 | 枚举 | 描述 |
---|---|---|
Reserved | 0 | 已预留 |
CONNECT | 1 | 客户端请求连接到服务器 |
CONNACK | 2 | 连接确认 |
PUBLISH | 3 | 发布讯息 |
PUBACK | 4 | 发布确认 |
PUBREC | 5 | 发布收到(保证交付部分1) |
PUBREL | 6 | 发布版本(保证交付的第2部分) |
PUBCOMP | 7 | 发布完成(保证交付的第3部分) |
SUBSCRIBE | 8 | 客户订阅请求 |
SUBACK | 9 | 订阅确认 |
UNSUBSCRIBE | 10 | 客户退订请求 |
UNSUBACK | 11 | 退订确认 |
PINGREQ | 12 | PING请求 |
PINGRESP | 13 | PING回应 |
DISCONNECT | 14 | 客户端正在断开连接 |
Reserved | 15 | 已预留 |
DUP标志占字节一中的第3位,
当客户端或服务器尝试重新传递PUBLISH,PUBREL, SUBSCRIBE或UNSUBSCRIBE消息时,将设置此标志。这适用于QoS值大于零(0)且需要确认的消息。当DUP位置1时,变量头包括消息ID。
接收者应将此标志视为有关消息是否先前已被接收的提示。不应依靠它来检测重复项。
QoS等级占了第2到第1位,它表示了此PUBLISH消息传递的服务质量。
QoS 价值 | 第二位 | 第一位 | 描述 | ||
---|---|---|---|---|---|
0 | 0 | 0 | 最多一次 | Fire and Forget(发送完后就不管了,不用管目标有没有收到) | <=1 |
1 | 0 | 1 | 最少一次 | Acknowledged delivery(接收端一定要确认收到信息,没收到就继续发,发到目标收到为止) | >=1 |
2 | 1 | 0 | 只能一次 | Assured delivery(不惜一切代价把信息一次性地交付给目标) | =1 |
3 | 1 | 1 | 保留 |
保留位于第0位,
如果用户在发送给服务端的信息中将该位置“1”,服务器就会保留发给给客户端的信息。
字节二:
此字节表示当前消息中剩余的字节数,包括变量头和有效载荷中的数据。
一个字节可最多表示127个字节的消息,这里可能就有人问了一个字节最大是1111 1111按道理来说应该是256才对啊?因为mqtt协议最多可以以4字节的形式来表示剩余消息中的字节数,所以每个字节的第8位数字表示是否需要再使用一个字节来表示剩下消息中的字节数,如果在第8位置“1”就表示再使用一个字节,置“0”就表示不调用。
可变头
下表显示了变量头的格式示例:
Description | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
---|---|---|---|---|---|---|---|---|---|
Protocol Name | |||||||||
byte 1 | Length MSB (0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
byte 2 | Length LSB (6) | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
byte 3 | ‘M’ | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
byte 4 | ‘Q’ | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 |
byte 5 | ‘I’ | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 |
byte 6 | ‘s’ | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
byte 7 | ‘d’ | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
byte 8 | ‘p’ | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
Protocol Version Number | |||||||||
byte 9 | Version (3) | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
Connect Flags | |||||||||
byte 10 | User name flag (1) Password flag (1) Will RETAIN (0) Will QoS (01) Will flag (1) Clean Session (1) |
1 | 1 | 0 | 0 | 1 | 1 | 1 | x |
Keep Alive timer | |||||||||
byte 11 | Keep Alive MSB (0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
byte 12 | Keep Alive LSB (10) | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
协议名称(Protocol Name)
协议名称位于MQTT CONNECT消息的变量标头中 。此字段是UTF编码的字符串。
协议版本(Protocol Version Number)
该字段是一个8位无符号值,表示客户端使用的协议的修订级别。
连接标志(Connect Flags)
Clean session,Will,Will QoS和保留标志存在于CONNECT消息的变量标头中。
清理会话标志(Clean Session)
位置:连接标志字节的位1。
如果设置为(0),则服务器必须在断开连接后存储客户端的订阅。这包括继续存储已订阅主题的QoS 1和QoS 2消息,以便在客户端重新连接时可以传递它们。服务器还必须在连接断开时保持正在传送的运行中消息的状态。在客户端重新连接之前,必须保留此信息。
如果设置为(1),则服务器必须丢弃有关客户端的任何先前维护的信息,并将连接视为“干净”。当客户端断开连接时,服务器还必须放弃任何状态。
预设置标志(Will flag)
位置:连接标志字节的位2。
Will消息定义当服务器在与客户端通信期间遇到I / O错误,或者客户端无法在Keep Alive计时器计划内进行通信时,服务器将代表客户端发布消息。服务器从客户端接收到DISCONNECT消息后,不会触发发送Will消息的操作。
如果设置了Will标志,则Will QoS和Will Retain字段必须出现在Connect标志字节中,而Will Topic和Will Message字段必须出现在有效负载中。
QoS
位置:连接标志字节的第4位和第3位。
如果客户端非自愿断开连接,则连接的客户端在Will消息的Will QoS字段中指定QoS级别。Will消息在CONNECT消息的有效负载中定义。
如果设置了Will标志,则Will QoS字段为必填字段,否则其值将被忽略。
Will QoS的值为0(0x00),1(0x01)或2(0x02)。下表显示了Will QoS标志。
将保留标志(will retain)
位置:连接标志字节的第5位。
Will Retain标志表示客户端是否意外断开连接时,服务器是否应保留由服务器代表客户端发布的Will消息。
如果设置了Will标志,则Will Retain标志是必需的,否则将被忽略。
用户名和密码标志(username and password flag)
位置:连接标志字节的第6位和第7位。
连接客户端可以指定用户名和密码,并且设置标志位表示CONNECT消息的有效负载中包括用户名和可选的密码。
如果设置了“用户名”标志,则“用户名”字段是必填字段,否则将忽略其值。如果设置了密码标志,则密码字段是必填字段,否则其值将被忽略。在不提供用户名的情况下提供密码是无效的。
保持活动计时器(Keep Alive timer)
保持活动计时器(以秒为单位)定义了从客户端收到的消息之间的最大时间间隔。它使服务器能够检测到与客户端的网络连接已断开,而不必等待长时间的TCP / IP超时。客户有责任在每个“保持活动”时间段内发送消息。在此时间段内没有数据相关消息的情况下,客户端会发送PINGREQ消息,服务器会通过PINGRESP消息进行确认 。
保持活动计时器可以通过MSB和LSB的顺序进行设置,它们分别占有2个字节。
负荷
以下类型的MQTT命令消息具有有效负载:
-
连接
- 有效负载包含一个或多个UTF-8编码的字符串。他们为客户端指定了一个无歧义的标识符,一个Will主题和消息以及要使用的用户名和密码。除了第一个以外的所有都是可选的,它们的存在是根据变量头中的标志确定的。
-
订阅
- 有效负载包含客户端可以订阅的主题名称和QoS级别的列表。这些字符串是UTF编码的。
-
后退
- 有效负载包含已授权QoS级别的列表。这些是服务器管理员已允许客户端订阅特定主题名称的QoS级别。授予的QoS级别以与相应的SUBSCRIBE消息中的主题名称相同的顺序列出。
- 学累了?听首歌吧!