MQTT V3.1协议规范
作者:
国际商业机器公司(IBM)
Eurotech
抽象
MQ遥测传输(MQTT)是一种基于代理的轻量级发布/订阅消息传递协议,旨在实现开放,简单,轻量且易于实现。这些特性使其非常适合在受限环境中使用,例如但不限于:
- 网络昂贵,带宽低或不可靠的地方
- 在具有有限处理器或内存资源的嵌入式设备上运行时
协议的特点包括:
- 发布/订阅消息模式,用于提供一对多的消息分发和应用程序的分离
- 与有效负载内容无关的消息传输
- 使用TCP / IP提供基本的网络连接
- 消息传递的三种服务质量:
- “最多一次”,根据底层TCP / IP网络的最佳努力传递消息。可能会发生消息丢失或重复。例如,该水平可以用于环境传感器数据,其中如果个体读数丢失则无关紧要,因为下一个读数将很快发布。
- “至少一次”,确保消息到达但可能发生重复。
- “恰好一次”,确保消息准确到达一次。例如,此级别可用于计费系统,其中重复或丢失的消息可能导致应用不正确的费用。
- 小的传输开销(固定长度的报头只有2个字节),协议交换最小化以减少网络流量
- 使用“最后遗嘱和遗嘱”功能通知相关方异常断开客户端的机制
版权声明
©1999-2010 Eurotech,International Business Machines Corporation(IBM)。版权所有。
复制和显示MQ遥测传输规范(“规范”)的许可,在任何媒体中免费或特许权使用费,特此授予Eurotech和国际商业机器公司(IBM)(统称“作者”),前提是您包括以下是您制作的规范的所有副本或其中的部分内容:
- 在作者网站之一的规范的链接或URL。
- 版权声明如规范中所示。
作者均同意在合理的,非歧视性的条款和条件下,向他们授予他们认为实施规范所必需的各自专利的免版税许可。规格按“原样”提供,且作者不作任何陈述或明示或暗示的保证,包括但不限于对适销性,特定用途的适用性,非侵权性或所有权的保证; 本规范的内容适用于任何目的; 或者,此类内容的实施不会侵犯任何第三方专利,版权,商标或其他权利。作者不对因任何使用或分发引起的或与之相关的任何直接,间接,特殊,偶发或继发损害不承担任何责任。规范。
未经特定的事先书面许可,不得以任何方式使用作者的名称和商标,包括与规范或其内容相关的广告或宣传。本规范中的版权所有权始终由作者保留。
不得以暗示,禁止反言或其他方式授予任何其他权利。
目录
- 1.简介
- 1.1。变化
- 2.消息格式
- 3.命令消息
- 3.1。CONNECT
- 3.2。CONNACK
- 3.3。发布
- 3.4。PUBACK
- 3.5。PUBREC
- 3.6。PUBREL
- 3.7。PUBCOMP
- 3.8。订阅
- 3.9。SUBACK
- 3.10。退订
- 3.11。UNSUBACK
- 3.12。PINGREQ
- 3.13。PINGRESP
- 3.14。断开
- 4.流动
- 附录A.
1.简介
该规范分为三个主要部分:
- 所有数据包类型共有的消息格式,
- 每种数据包类型的具体细节,
- 数据包如何在客户端和服务器之间流动。
附录中提供了有关如何使用主题通配符的信息。
1.1。变化
以下是MQTT V3和MQTT V3.1之间的更改:
- 现在可以使用CONNECT数据包发送用户名和密码
- CONNACK数据包的新返回码,用于安全问题
- 澄清客户端未被告知未经授权的PUBLISH或SUBSCRIBE命令,并且即使未执行命令,也应完成正常的MQTT流程。
- MQTT中的字符串现在支持完整的UTF-8,而不仅仅是US-ASCII子集。
使用CONNECT数据包传递的协议版本号在此修订版中保持不变,并保持为“3”。现有的MQTT V3服务器实现应该能够接受来自支持此修订的客户端的连接,只要它们正确地遵守“剩余长度”字段,因此忽略额外的安全信息。
2.消息格式
每个MQTT命令消息的消息头包含一个fixedheader。某些消息还需要变量头和有效负载。以下各节介绍了邮件头的每个部分的格式:
2.1。固定标题
每个MQTT命令消息的消息头包含一个fixedheader。下表显示了固定的标头格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型 | DUP标志 | QoS级别 | 保留 | ||||
字节2 | 剩余长度 |
字节1
包含消息类型和标志(DUP,QoS级别和RETAIN)字段。
字节2
(至少一个字节)包含剩余长度字段。
以下各节介绍了这些字段。所有数据值都采用大端顺序:高位字节位于低位字节之前。16位字在线上显示为最高有效字节(MSB),后跟最低有效字节(LSB)。
消息类型
位置:字节1,位7-4。
表示为4位无符号值。该协议的此版本的枚举如下表所示。
助记符 | 列举 | 描述 |
保留的 | 0 | 保留的 |
CONNECT | 1 | 客户端请求连接到服务器 |
CONNACK | 2 | 连接确认 |
发布 | 3 | 发布消息 |
PUBACK | 4 | 发布确认 |
PUBREC | 5 | 发布收到(保证交付第1部分) |
PUBREL | 6 | 发布发布(保证交付第2部分) |
PUBCOMP | 7 | 发布完成(保证交付第3部分) |
订阅 | 8 | 客户订阅请求 |
SUBACK | 9 | 订阅确认 |
退订 | 10 | 客户取消订阅请求 |
UNSUBACK | 11 | 取消订阅确认 |
PINGREQ | 12 | PING请求 |
PINGRESP | 13 | PING响应 |
断开 | 14 | 客户端正在断开连接 |
保留的 | 15 | 保留的 |
旗
字节1的其余位包含字段DUP,QoS和RETAIN。位位置被编码以表示标志,如下表所示。
位位置 | Name | 描述 |
3 | DUP | 重复发送 |
2-1 | 服务质量 | 服务质量 |
0 | 保留 | 保留标志 |
DUP
位置:字节1,位3。
当客户端或服务器尝试重新传送时,将设置此标志发布,PUBREL,订阅要么退订信息。这适用于QoS值大于零(0)的消息,并且需要确认。当DUP位置1时,变量头包括消息ID。
收件人应将此标志视为是否先前已收到该消息的提示。不应该依赖它来检测重复。
服务质量
位置:字节1,位2-1。
此标志表示交付a的保证级别发布信息。QoS级别如下表所示。
QoS值 | 第2位 | 第1位 | 描述 | ||
0 | 0 | 0 | 最多一次 | 火和忘记 | <= 1 |
1 | 0 | 1 | 至少一次 | 已确认交货 | > = 1 |
2 | 1 | 0 | 恰好一次 | 保证交货 | =1 |
3 | 1 | 1 | 保留的 |
保留
位置:字节1,位0。
此标志仅用于发布消息。当客户端向服务器发送PUBLISH时,如果设置了Retain标志(1),则服务器应该在将消息传递给当前订户后保持该消息。
当在主题上建立新订阅时,应该将具有该主题的最后保留消息发送给设置了Retain标志的订户。如果没有保留的消息,则不发送任何内容
这在发布者基于“异常报告”的基础上发送消息时很有用,其中消息之间可能需要一段时间。这允许新订户立即接收具有保留或最后已知良好值的数据。
当服务器由于原始PUBLISH到达时已经存在的订阅而向客户端发送PUBLISH时,不管原始PUBLISH的Retain标志如何,都不应设置Retain标志。这允许客户端区分由于保留而正在接收的消息和“实时”接收的消息。
应保留重新启动服务器的保留消息。
如果服务器收到具有零长度有效负载的消息并且在同一主题上设置了保留标志,则可以删除保留的消息。
剩余长度
位置:字节2。
表示当前消息中剩余的字节数,包括变量头和有效负载中的数据。
可变长度编码方案使用单个字节用于长达127个字节的消息。较长的消息处理如下。每个字节的七个比特对剩余长度数据进行编码,第八个比特表示表示中的任何后续字节。每个字节编码128个值和一个“连续位”。例如,数字64decimal被编码为单个字节,十进制值64,十六进制0x40。number321十进制(= 65 + 2 * 128)编码为两个字节,最低有效率。第一个字节65 + 128 = 193.注意,顶部位设置为至少指示一个后续字节。第二个字节是2。
该协议将表示中的字节数限制为最多四个。这允许应用程序发送最多268 435 455(256 MB)的消息。这个数字在线上的表示是:0xFF,0xFF,0xFF,0x7F。
下表显示了由不断增加的字节数表示的剩余长度值。
数字 | 从 | 至 |
1 | 0(0x00) | 127(0x7F) |
2 | 128(0x80,0x01) | 16 383(0xFF,0x7F) |
3 | 16 384(0x80,0x80,0x01) | 2 097 151(0xFF,0xFF,0x7F) |
4 | 2 097 152(0x80,0x80,0x80,0x01) | 268 435 455(0xFF,0xFF,0xFF,0x7F) |
将十进制数(X)编码为可变长度编码方案的算法如下:
do digit = X MOD 128 X = X DIV 128 // if there are more digits to encode, set the top bit of this digit if ( X > 0 ) digit = digit OR 0x80 endif 'output' digit while ( X> 0 )
哪里MOD
是模运算符(%
INC)DIV
是整数除法(/
在C),和OR
有点或(|
在C)。
用于解码剩余长度字段的算法如下:
multiplier = 1 value = 0 do digit = 'next digit from stream' value += (digit AND 127) * multiplier multiplier *= 128 while ((digit AND 128) != 0)
哪里AND
是比特和运营商(&
在C)。
当此算法终止时,value
包含剩余长度(以字节为单位)。
剩余长度编码不是变量头的一部分。用于编码剩余长度的字节数不会导致剩余长度的值。可变长度“扩展字节”是固定标题的一部分,而不是变量标题。
2.2。变量头
某些类型的MQTT命令消息还包含可变标头组件。它位于固定标头和有效负载之间。
可变长度剩余长度字段不是变量头的一部分。“剩余长度”字段的字节不会影响“剩余长度”值的字节数。此值仅考虑变量头和有效负载。看到固定标题欲获得更多信息。
变量头字段的格式在以下部分中描述,按照它们必须出现在标题中的顺序:
协议名称
协议名称存在于MQTT的变量头中CONNECT信息。此字段是UTF编码的字符串,表示协议名称MQIsdp,如图所示大写。
协议版本
协议版本存在于a的变量头中CONNECT信息。
该字段是一个8位无符号值,表示客户端使用的协议的修订级别。当前版本的协议3(0x03)的Protocolversion字段的值如下表所示。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 协议版本 | |||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
连接标志
Clean会话,Will,Will,QoS和Retain标志存在于a的变量头中CONNECT信息。
清洁会议标志
位置:连接标志字节的第1位。
如果未设置(0),则服务器必须在断开连接后存储客户端的订阅。这包括继续为订阅主题存储QoS 1和QoS 2消息,以便在客户端重新连接时传递它们。服务器还必须保持在连接丢失时传送的正在传送的消息的状态。必须保留此信息,直到客户端重新连接。
如果设置为(1),则服务器必须丢弃先前维护的有关客户端的任何信息,并将连接视为“干净”。当客户端断开连接时,服务器还必须丢弃anystate。
通常,客户端将以一种模式或另一种模式运行而不会更改。选择将取决于应用程序。干净的会话客户端不会收到恶意信息,每次连接时都必须重新订阅。非干净会话客户端将不会错过在断开连接时发布的任何QoS 1或QoS 2消息。永远不会存储QoS 0消息,因为它们是在尽力而为的基础上提供的。
这面旗子以前被称为“干净的开始”。它已经被重命名,以便将它应用于整个会话的事实进行整理,而不仅仅是初始连接。
服务器可以提供用于清除客户端的存储信息的管理机制,当知道客户端永远不会重新连接时,可以使用该管理机制。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 用户名标志 | 密码标志 | 保留 | 将QoS | 将旗帜 | 清洁会议 | 保留的 | |
| X | X | X | X | X | X |
| X |
该字节的位0未在协议的当前版本中使用。它留作将来使用。
会举旗
位置:连接标志字节的第2位。
Will消息定义当服务器在与客户端通信期间遇到I / O错误,或者客户端未能在Keep Alive计时器调度内进行通信时,服务器代表客户端发布消息。发送Will消息不是由服务器从客户端接收DISCONNECT消息触发的。
如果设置了Will标志,则Will QoS和Will Retain字段必须出现在Connect标志字节中,并且Will Topic和WillMessage字段必须存在于有效负载中。
Will标志的格式如下表所示。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 用户名标志 | 密码标志 | 保留 | 将QoS | 将旗帜 | 清洁会议 | 保留的 | |
| X | X | X | X | X |
| X | X |
该字节的位0未在协议的当前版本中使用。它留作将来使用。
将QoS
位置:连接标志字节的第4位和第3位。
连接客户端在Will QoS字段中指定Will消息中的QoS等级,该消息是在客户端被非自愿地断开连接的情况下发送的。Will消息在a的有效负载中定义CONNECT信息。
如果设置了Will标志,则Will QoS字段是必需的,否则忽略其值。
Will QoS的值为0(0x00),1(0x01)或2(0x02)。Will QoS标志如下表所示。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 用户名标志 | 密码标志 | 保留 | 将QoS | 将旗帜 | 清洁会议 | 保留的 | |
| X | X | X |
|
| 1 | X | X |
该字节的位0未在协议的当前版本中使用。它留作将来使用。
将保留旗帜
位置:连接标志字节的第5位。
Will Retain标志指示服务器是否应该获得Will消息,该消息由服务器代表客户端在客户端意外断开的情况下发布。
如果设置了Will标志,则Will Retain标志是必需的,否则,它将被忽略。Will Retain标志的格式如下表所示。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 用户名标志 | 密码标志 | 保留 | 将QoS | 将旗帜 | 清洁会议 | 保留的 | |
| X | X |
| X | X | 1 | X | X |
该字节的位0未在协议的当前版本中使用。它留作将来使用。
用户名和密码标志
位置:连接标志字节的第6位和第7位。
连接客户端可以指定用户名和密码,并且设置标志位表示用户名和可选的密码包含在有效负载中。CONNECT信息。
如果设置了“用户名”标志,则“用户名”字段是必填字段,否则忽略其值。如果设置了密码标志,则密码字段是必填字段,否则忽略其值。在不提供用户名的情况下提供密码无效。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 用户名标志 | 密码标志 | 保留 | 将QoS | 将旗帜 | 清洁会议 | 保留的 | |
|
|
| X | X | X | X | X | X |
该字节的位0未在协议的当前版本中使用。它留作将来使用。
保持活着的计时器
Keep Alive计时器存在于MQTT的变量头中CONNECT信息。
Keep Alive计时器(以秒为单位)定义了从客户端收到的消息之间的最大时间间隔。它使服务器能够检测到客户端的网络连接已丢失,而无需等待长TCP / IP超时。客户有责任在每个Keep Alive时间段内发送消息。在该时间段期间没有与数据相关的消息时,客户端发送aPINGREQ消息,服务器用a确认PINGRESP信息。
如果服务器在保持活动时间段内没有从客户端收到消息(客户端允许半个时间段的“宽限期”),则会断开客户端的连接,就好像客户端发送了一个断开信息。此操作不会影响任何客户端的订阅。看到断开更多细节。
如果客户没有收到PINGRESP发送后的保持活动时间段内的消息PINGREQ,它应该关闭TCP / IP套接字连接。
Keep Alive计时器是一个16位值,表示该时间段的秒数。实际值是特定于应用程序的,但典型值是几分钟。最大值约为18小时。值为零(0)表示客户端未断开连接。
Keep Alive定时器的格式如下表所示。保持活动定时器的2个字节的顺序是MSB,然后是LSB(big-endian)。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 保持活力MSB | |||||||
| 保持活着LSB |
连接返回代码
连接返回码在a的变量头中发送CONNACK信息。
该字段定义一个字节无符号返回码。下表中显示的值的含义特定于消息类型。返回码为零(0)通常表示成功。
列举 | HEX | 含义 |
0 | 为0x00 | 已接受连接 |
1 | 0×01 | 拒绝连接:不可接受的协议版本 |
2 | 0×02 | 连接被拒绝:标识符被拒绝 |
3 | ×03 | 连接被拒绝:服务器不可用 |
4 | 0×04 | 连接被拒绝:用户名或密码错误 |
5 | 0×05 | 连接被拒绝:未经授权 |
6-255 |
| 保留供将来使用 |
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 退货代码 |
主题名称
主题名称存在于MQTT的变量头中发布信息。
主题名称是标识有效数据发布的信息通道的关键。订户使用密钥来识别他们想要接收公开信息的信息渠道。
主题名称是UTF编码的字符串。请参阅有关的部分MQTT和UTF-8欲获得更多信息。主题名称的长度上限为32,767个字符。
2.3。有效载荷
以下类型的MQTT命令消息具有有效负载:
有效负载包含一个或多个UTF-8编码的字符串。它们为客户端指定了unqiue标识符,Will主题和消息以及要使用的用户名和密码。除第一个之外的所有都是可选的,它们的存在是根据变量头中的标志确定的。
订阅
有效负载包含客户端可以订阅的主题名称列表以及QoS级别。这些字符串是UTF编码的。
SUBACK
有效负载包含授予的QoS级别列表。这些是服务器管理员允许客户端订阅特定主题名称的QoS级别。授予的QoS级别以与相应SUBSCRIBE消息中的主题名称相同的顺序列出。
有效载荷的一部分发布message仅包含特定于应用程序的数据。没有关于数据的性质或内容的假设,并且该部分消息被视为BLOB。
如果希望应用程序将压缩应用于payloaddata,则需要在应用程序中定义适当的有效负载标记字段以处理压缩详细信息。您无法在固定或变量标头中定义特定于应用程序的标志。
2.4。消息标识符
消息标识符存在于以下MQTT消息的变量头中:PUBLISH,PUBACK,PUBREC,PUBREL,PUBCOMP,SUBSCRIBE,SUBACK,UNSUBSCRIBE,UNSUBACK。
消息标识符(消息ID)字段仅出现在消息中,其中固定报头中的QoS比特指示QoS等级1或2。见章节服务质量水平和流量欲获得更多信息。
消息ID是16位无符号整数,在特定通信方向的“飞行中”消息集中必须是唯一的。它通常从一个消息到下一个消息恰好增加一个,但不需要这样做。
客户端将维护自己的消息ID列表,与其所连接的服务器使用的消息ID分开。客户端可以在接收具有消息ID 1的PUBLISH的同时发送具有消息ID 1的PUBLISH。
消息标识符的两个字节的顺序是MSB,然后是LSB(大端)。
不要使用消息ID 0.它保留为无效的消息ID。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 消息标识符MSB | |||||||
| 消息标识符LSB |
2.5。MQTT和UTF-8
UTF-8是Unicode字符串的有效编码,它优化了ASCII字符的编码,以支持基于文本的通信。
在MQTT中,字符串以两个字节为前缀来表示长度,如下表所示。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 字符串长度MSB | |||||||
字节2 | 字符串长度LSB | |||||||
字节3 ... | 编码字符数据 |
字符串长度是编码字符串字符的字节数,而不是字符数。例如,字符串OTWP以UTF-8编码,如下表所示。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息长度MSB(0x00) | |||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
字节2 | 消息长度LSB(0x04) | |||||||
| 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
字节3 | 'O'(0x4F) | |||||||
| 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 |
字节4 | 'T'(0x54) | |||||||
| 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 |
字节5 | 'W'(0x57) | |||||||
| 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 |
字节6 | 'P'(0x50) | |||||||
| 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 |
JavawriteUTF()
和readUTF()
datastream方法使用此格式。
2.6。未使用的位
标记为未使用的任何位应设置为零(0)。
3.命令消息
- CONNECT
- CONNACK
- 发布
- PUBACK
- PUBREC
- PUBREL
- PUBCOMP
- 订阅
- SUBACK
- 退订
- UNSUBACK
- PINGREQ
- PINGRESP
- 断开
3.1。CONNECT - 客户端请求与服务器的连接
从客户端到服务器建立TCP / IP套接字连接时,必须使用CONNECT流创建协议级会话。
固定标题
固定标题格式如下表所示。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(1) | DUP标志 | QoS级别 | 保留 | ||||
| 0 | 0 | 0 | 1 | X | X | X | X |
字节2 | 剩余长度 |
CONNECTmessage中未使用DUP,QoS和RETAIN标志。
剩余长度是变量头的长度(12个字节)和有效负载的长度。这可以是多字节字段。
变量头
下面的表格中显示了变量头的格式示例。
| 描述 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
协议名称 | |||||||||
字节1 | 长度MSB(0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
字节2 | 长度LSB(6) | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
字节3 | 'M' | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
字节4 | 'Q' | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 |
字节5 | '一世' | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 |
字节6 | 'S' | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
字节7 | 'd' | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
字节8 | 'P' | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
协议版本号 | |||||||||
字节9 | 版本(3) | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
连接标志 | |||||||||
字节10 | 用户名标志(1) | 1 | 1 | 0 | 0 | 1 | 1 | 1 | X |
保持活着的计时器 | |||||||||
字节11 | 保持活力MSB(0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
字节12 | 保持活力LSB(10) | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
用户名标志
设置(1)。
密码标志
设置(1)。
清洁会话标志
设置(1)。
保持活着的计时器
设置为10秒(0x000A)。
请留言
- 将标志设置(1)
- QoS字段是否为1
- RETAIN标志是否清晰(0)
有效载荷
CONNECT消息的有效负载包含一个或多个UTF-8编码字符串,基于变量头中的标志。字符串(如果存在)必须按以下顺序显示:
客户标识符
第一个UTF编码的字符串。客户端标识符(客户端ID)长度在1到23个字符之间,并且唯一地标识服务器的客户端。它在连接到单个服务器的所有客户端上必须是唯一的,并且是处理QoS级别为1和2的消息ID消息的关键。如果客户端ID包含超过23个字符,则服务器使用CONNACK返回响应CONNECT消息代码2:标识符被拒绝。
将主题
如果设置了Will Flag,则这是下一个UTF-8编码的字符串。遗嘱消息将发布到Will Topic。QoS级别由Will QoS字段定义,RETAIN状态由变量头中的Will RETAIN标志定义。
将消息
如果设置了Will Flag,则这是下一个UTF-8编码的字符串。如果客户端意外断开连接,Will Message将定义发布到Will Topic的消息内容。这可能是零长度消息。
尽管Will Message消息在CONNECT消息中是UTF-8编码的,但当它发布到Will Topic时,只发送消息的字节,而不是前两个长度字节。因此,消息必须仅包含7位ASCII字符。
用户名
如果设置了用户名标志,则这是下一个UTF编码的字符串。用户名标识正在连接的用户的名称,可用于身份验证。建议用户名保持12个字符或更少,但不是必需的。
请注意,为了与原始MQTT V3规范兼容,固定标头中的“剩余长度”字段优先于“用户名”标志。服务器实现必须允许设置用户名标志,但缺少用户名字符串。这是有效的,应该允许连接继续。
密码
如果设置了密码标志,则这是下一个UTF编码的字符串。与正在连接的用户对应的密码,可用于验证。建议将密码保留为12个字符或更少,但不是必需的。
请注意,为了与原始MQTT V3规范兼容,固定标头中的“剩余长度”字段优先于“密码”标志。服务器实现必须允许设置密码标志的可能性,但缺少密码字符串。这是有效的,应该允许连接继续。
响应
服务器发送CONNACK消息以响应来自客户端的CONNECT消息。
如果服务器在建立TCP / IP连接后的合理时间内没有收到CONNECT消息,则服务器应关闭连接。
如果客户端在合理的时间内没有从服务器收到CONNACK消息,则客户端应关闭TCP / IPsocket连接,并通过打开服务器的新套接字并发出CONNECT消息来重新启动会话。
在这两种情况中,“合理”的时间量取决于应用类型和通信基础设施。
如果具有相同客户端ID的客户端已连接到服务器,则在完成新客户端的CONNECT流之前,服务器必须断开“旧”客户端的连接。
如果客户端发送无效的CONNECT消息,则服务器应关闭连接。这包括提供无效协议名称或协议版本号的CONNECT消息。如果服务器可以解析足够的CONNECT消息以确定已经请求了无效协议,则它可能会尝试在丢弃连接之前发送包含“拒绝连接:不可接受的协议版本”代码的CONNACK。
3.2。CONNACK - 确认连接请求
CONNACK消息是服务器响应a发送的消息CONNECT客户要求。
固定标题
固定标题格式如下表所示。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(2) | DUP标志 | QoS标志 | 保留 | ||||
| 0 | 0 | 1 | 0 | X | X | X | X |
字节2 | 剩余长度(2) | |||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
CONNACK消息中不使用DUP,QoS和RETAIN标志。
变量头
变量头格式如下表所示。
| 描述 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
主题名称压缩响应 | |||||||||
字节1 | 保留值。不曾用过。 | X | X | X | X | X | X | X | X |
连接退货代码 | |||||||||
字节2 | 退货代码 |
|
|
|
|
|
|
|
|
单字节无符号Connect返回代码字段的值如下表所示。
列举 | HEX | 含义 |
0 | 为0x00 | 已接受连接 |
1 | 0×01 | 拒绝连接:不可接受的协议版本 |
2 | 0×02 | 连接被拒绝:标识符被拒绝 |
3 | ×03 | 连接被拒绝:服务器不可用 |
4 | 0×04 | 连接被拒绝:用户名或密码错误 |
5 | 0×05 | 连接被拒绝:未经授权 |
6-255 |
| 保留供将来使用 |
如果唯一clientidentifier的长度不在1到23个字符之间,则发送返回码2(拒绝标识符)。
有效载荷
没有有效载荷。
3.3。发布 - 发布消息
客户端向服务器发送PUBLISH消息以分发给感兴趣的订户。每个PUBLISH消息都与主题名称(也称为主题或频道)相关联。这是一个分层名称空间,用于定义信息源的分类,订阅者可以为其注册兴趣。发布到特定主题名称的消息将传递给该主题的connectedsubscribers。
如果客户端订阅了一个或多个主题,则发布到这些主题的任何消息都由服务器作为PUBLISH消息发送给客户端。
固定标题
下表显示了固定的标头格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(3) | DUP标志 | QoS级别 | 保留 | ||||
| 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 |
字节2 | 剩余长度 |
QoS级别
设为1.请参阅服务质量更多细节。
DUP标志
设为零(0)。这意味着该消息是第一次发送。看到DUP更多细节。
保留标志
设为零。这意味着不保留。看到保留更多细节。
剩余长度字段
变量头的长度加上有效负载的长度。它可以是多字节字段。
变量头
变量头包含以下字段:
主题名称
UTF编码的字符串。
这不能包含主题通配符字符。
当使用通配符预订的客户端收到此字符串时,此字符串将是原始发布者指定的绝对主题不客户端使用的订阅字符串。
消息ID
存在具有QoS级别1和QoS级别2的消息。请参阅消息标识符更多细节。
下表显示了PUBLISHmessage的示例变量头。
领域 | 值 |
主题名称: | “A / B” |
QoS级别 | 1 |
消息ID: | 10 |
在这种情况下,变量头的格式如下表所示。
| 描述 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
主题名称 | |||||||||
字节1 | 长度MSB(0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
字节2 | 长度LSB(3) | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
字节3 | 'a'(0x61) | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
字节4 | '/'(0x2F) | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
字节5 | 'b'(0x62) | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 |
消息标识符 | |||||||||
字节6 | 消息ID MSB(0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
字节7 | 消息ID LSB(10) | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
有效载荷
包含要发布的数据。数据的内容和格式是特定于应用程序的。fixedheader中的Remaining Length字段包括变量头长度和有效负载长度。因此,PUBLISH包含0长度有效载荷是有效的。
响应
对PUBLISH消息的响应取决于QoS级别。下表显示了预期的反应。
QoS级别 | 预期的回应 |
QoS 0 | 没有 |
QoS 1 | PUBACK |
QoS 2 | PUBREC |
操作
PUBLISH消息可以从发布者发送到服务器,也可以从服务器发送到订阅者。收件人收到邮件时的操作取决于邮件的QoS级别:
QoS 0
将消息提供给任何感兴趣的各方。
QoS 1
将消息记录到持久存储,使其可供任何感兴趣的各方使用,并将PUBACK消息返回给发件人。
QoS 2
将消息记录到持久存储,不要让感兴趣的各方可用,并将PUBREC消息返回给发送方。
如果服务器收到该消息,则感兴趣的方意味着订阅者关于PUBLISH消息的主题。如果订阅者接收到该消息,则感兴趣的各方意味着该客户端上已经订阅了一个或多个主题的应用程序,并且正在等待来自服务器的消息。
看到服务质量水平和流量更多细节。
请注意,如果服务器实现未授权客户端进行PUBLISH,则无法通知该客户端。因此,必须根据正常的QoS规则做出肯定的确认,并且客户端将会这样做不被告知,它无权发布消息。
3.4。PUBACK - 发布确认
PUBACK消息是对a的响应发布QoS级别1的消息。服务器响应来自发布客户端的PUBLISH消息发送PUBACK消息,并由asubscriber响应发布来自服务器的消息。
固定标题
下表显示了固定标头的格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(4) | DUP标志 | QoS级别 | 保留 | ||||
| 0 | 1 | 0 | 0 | X | X | X | X |
字节2 | 剩余长度(2) | |||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
QoS级别
不曾用过。
DUP标志
不曾用过。
保留标志
不曾用过。
剩余长度字段
这是变量头的长度(2个字节)。它可以是多字节字段。
变量头
包含的消息标识符(消息ID)发布正在确认的消息。下面的表格显示了变量头的格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息ID MSB | |||||||
字节2 | 消息ID LSB |
有效载荷
没有有效载荷。
操作
当客户端收到PUBACK消息时,它会丢弃原始消息,因为它也被服务器接收(并记录)。
3.5。PUBREC - 确保收到发布(第1部分)
PUBREC消息是对a的响应发布QoS等级2的消息。它是QoS等级2协议流的第二个消息。服务器响应a发送PUBREC消息发布来自发布客户端的消息,或者由asubscriber响应的消息发布来自服务器的消息。
固定标题
下表显示了固定的标头格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(5) | DUP标志 | QoS级别 | 保留 | ||||
| 0 | 1 | 0 | 1 | X | X | X | X |
字节2 | 剩余长度(2) | |||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
QoS级别
不曾用过。
DUP标志
不曾用过。
保留标志
不曾用过。
剩余长度字段
变量头的长度(2个字节)。它可以是多字节字段。
变量头
变量头包含已确认的消息ID发布。下表显示了变量标题的格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息ID MSB | |||||||
字节2 | 消息ID LSB |
有效载荷
没有有效载荷。
操作
当收到PUBREC消息时,接收方将PUBREL消息发送给发送方,其消息ID与PUBREC消息相同。
3.6。PUBREL - Assured Publish Release(第2部分)
PUBREL消息是发布者对a的响应PUBREC来自服务器,或从服务器到a的消息PUBREC来自订户的消息。它是QoS 2协议流中的第三条消息。
固定标题
下表显示了固定的标头格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(6) | DUP标志 | QoS级别 | 保留 | ||||
| 0 | 1 | 1 | 0 | 0 | 0 | 1 | X |
字节2 | 剩余长度(2) | |||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
QoS级别
PUBREL消息使用QoS级别1,因为期望以a的形式进行确认PUBCOMP。重试的处理方式与发布消息。
DUP标志
设为零(0)。这意味着该消息是第一次发送。看到DUP更多细节。
保留标志
不曾用过。
剩余长度字段
变量头的长度(2个字节)。它可以是多字节字段。
变量头
变量头包含与之相同的消息IDPUBREC正在确认的消息。下表显示了变量头的格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息ID MSB | |||||||
字节2 | 消息ID LSB |
有效载荷
没有有效载荷。
操作
当服务器从发布者接收到PUBREL消息时,服务器使原始消息可供感兴趣的订户使用,并向发布者发送具有相同消息ID的PUBCOMP消息。当订阅者从服务器接收到PUBREL消息时,订阅者发出消息可供订阅应用程序使用,并将PUBCOMP消息发送到服务器。
3.7。PUBCOMP - 确保发布完成(第3部分)
此消息是服务器对a的响应PUBREL来自发布者的消息,或来自订阅者的响应PUBREL来自服务器的消息。它是QoS 2协议流程中的第四个也是最后一个消息。
固定标题
下表显示了固定的标头格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(7) | DUP标志 | QoS级别 | 保留 | ||||
| 0 | 1 | 1 | 1 | X | X | X | X |
字节2 | 剩余长度(2) | |||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
QoS级别
不曾用过。
DUP标志
不曾用过。
保留标志
不曾用过。
剩余长度字段
变量头的长度(2个字节)。它可以是多字节字段。
变量头
变量头包含与已确认的PUBREL消息相同的消息ID。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息ID MSB | |||||||
字节2 | 消息ID LSB |
有效载荷
没有有效载荷。
操作
当客户端收到PUBCOMP消息时,它会丢弃原始消息,因为它已经被传送到服务器一次。
3.8。订阅 - 订阅指定主题
SUBSCRIBE消息允许客户端向服务器注册对一个或多个主题名称的兴趣。发布到这些主题的消息将从服务器传递到客户端发布消息。SUBSCRIBE消息还指定订户想要接收已发布消息的QoS等级。
固定标题
下表显示了固定的标头格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(8) | DUP标志 | QoS级别 | 保留 | ||||
| 1 | 0 | 0 | 0 | 0 | 0 | 1 | X |
字节2 | 剩余长度 |
QoS级别
SUBSCRIBE消息使用QoS级别1来确认多个订阅请求。通过匹配消息ID来识别相应的SUBACK消息。重试的处理方式与发布消息。
DUP标志
设为零(0)。这意味着该消息是第一次发送。看到DUP更多细节。
保留标志
不曾用过。
剩余长度字段
有效载荷的长度。它可以是多字节字段。
变量头
变量头包含消息ID,因为SUBSCRIBEmessage的QoS级别为1.请参阅消息标识符更多细节。
下表显示了消息ID为10的变量头的示例格式。
| 描述 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
消息标识符 | |||||||||
字节1 | 消息ID MSB(0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
字节2 | 消息ID LSB(10) | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
有效载荷
SUBSCRIBE消息的有效载荷包含客户端想要订阅的主题名称列表,以及客户端想要接收消息的QoS级别。字符串是UTF编码的,QoS级别占用单个字节的2位。主题字符串可能具有特殊性主题通配符characters代表一组主题。这些主题/ QoS对连续打包,如下表中的示例有效负载所示。
主题名称 | “A / B” |
请求的QoS | 1 |
主题名称 | “光盘” |
请求的QoS | 2 |
SUBSCRIBE消息中的主题名称未压缩。
示例有效负载的格式如下表所示。
| 描述 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
主题名称 | |||||||||
字节1 | 长度MSB(0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
字节2 | 长度LSB(3) | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
字节3 | 'a'(0x61) | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
字节4 | '/'(0x2F) | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
字节5 | 'b'(0x62) | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 |
请求的QoS | |||||||||
字节6 | 请求的QoS(1) | X | X | X | X | X | X | 0 | 1 |
主题名称 | |||||||||
字节7 | 长度MSB(0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
字节8 | 长度LSB(3) | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
字节9 | 'c'(0x63) | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 |
字节10 | '/'(0x2F) | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
字节11 | 'd'(0x64) | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
请求的QoS | |||||||||
字节12 | 请求的QoS(2) | X | X | X | X | X | X | 1 | 0 |
假设授予所请求的QoS级别,则客户端接收发布消息小于或等于此级别,具体取决于发布者原始消息的QoS级别。例如,如果客户端具有对特定主题的QoS级别1订阅,则QoS级别为0发布该主题的消息以QoS级别0传递给客户端。一个QoS级别2发布对同一主题的消息被降级到QoS级别1以便传递给客户端。
对此的推论是,在QoS级别2订阅主题等同于说“我希望在其发布的QoS上接收关于该主题的消息”。
这意味着发布者负责确定可以在其处传递消息的最大QoS,但是订户能够将QoS转换为更适合其使用的QoS。消息的QoS从未升级过。
请求的QoS字段在每个UTF编码的主题名称后面的字节中编码,如下表所示。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 保留的 | 保留的 | 保留的 | 保留的 | 保留的 | 保留的 | QoS级别 | |
| X | X | X | X | X | X |
|
|
该字节的高6位不在协议的当前版本中使用。它们留作将来使用。
设置了两个QoS级别位的请求应被视为无效数据包并且连接已关闭。
响应
当它从客户端收到SUBSCRIBE消息时,服务器响应SUBACK消息。
服务器可能开始发送发布客户端收到SUBACK消息之前由于订阅而产生的消息。
请注意,如果服务器实现未授权客户端发出SUBSCRIBE请求,则无法通知该客户端。因此必须使用SUBACK做出肯定的确认,而客户端将会这样做不被告知它没有被授权订阅。
服务器可以选择授予比客户端请求的更低级别的QoS。如果服务器无法提供更高级别的QoS,则会发生这种情况。例如,如果服务器不提供可靠的持久性机制,则它可以选择仅在QoS 0处获取订阅。
3.9。SUBACK - 订阅确认
服务器向客户端发送SUBACK消息以确认收到a订阅信息。
SUBACK消息包含授予的QoS级别列表。SUBACK消息中grantQoS级别的顺序与相应主题名称的顺序相匹配订阅信息。
固定标题
下表显示了固定的标头格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(9) | DUP标志 | QoS级别 | 保留 | ||||
| 1 | 0 | 0 | 1 | X | X | X | X |
字节2 | 剩余长度 |
QoS级别
不曾用过。
DUP标志
不曾用过。
保留标志
不曾用过。
剩余长度字段
有效载荷的长度。它可以是多字节字段。
变量头
变量头包含正在确认的SUBSCRIBE消息的消息ID。下表显示了变量头的格式。
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息ID MSB | |||||||
字节2 | 消息ID LSB |
有效载荷
有效载荷包含授予的QoS级别的向量。每个级别对应于相应SUBSCRIBE消息中的主题名称。SUBACK消息中的QoS等级的顺序与SUBSCRIBE消息中的主题名称和请求的QoS对的顺序相匹配。通过变量头中的消息ID,您可以将SUBACK消息与相应的SUBSCRIBE消息进行匹配。
下表显示了以字节编码的授权QoS字段。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 保留的 | 保留的 | 保留的 | 保留的 | 保留的 | 保留的 | QoS级别 | |
| X | X | X | X | X | X |
|
该字节的高6位不在当前版本的协议中使用。它们留作将来使用。
下表显示了一个示例有效负载。
授予QoS | 0 |
授予QoS | 2 |
下表显示了此有效负载的格式。
| 描述 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 授权QoS(0) | X | X | X | X | X | X | 0 | 0 |
字节1 | 授权QoS(2) | X | X | X | X | X | X | 1 | 0 |
3.10。取消订阅 - 取消订阅指定主题
客户端向服务器发送UNSUBSCRIBE消息,以触发已命名主题的订阅。
固定标题
下表显示了一个示例固定标头格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(10) | DUP标志 | QoS级别 | 保留 | ||||
| 1 | 0 | 1 | 0 | 0 | 0 | 1 | X |
字节2 | 剩余长度 |
QoS级别
UNSUBSCRIBE消息使用QoS级别1来确认多个取消订阅请求。相应的UNSUBACK消息由消息ID标识。重试的处理方式与发布消息。
DUP标志
设为零(0)。这意味着该消息是第一次发送。看到DUP更多细节。
保留标志
不曾用过。
剩余长度
这是有效载荷的长度。它可以是多字节字段。
变量头
变量头包含消息ID,因为UNSUBSCRIBEmessage的QoS级别为1.请参阅消息标识符更多细节。
下表显示了消息ID为10的变量头的示例格式。
| 描述 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
消息标识符 | |||||||||
字节1 | 消息ID MSB(0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
字节2 | 消息ID LSB(10) | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
有效载荷
客户端取消订阅thepayload中指定的主题列表。字符串是UTF编码的并且是连续打包的。UNSUBSCRIBE消息中的主题名称未压缩。下表显示了示例有效负载。
主题名称 | “A / B” |
主题名称 | “光盘” |
下表显示了此有效负载的格式。
| 描述 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
主题名称 | |||||||||
字节1 | 长度MSB(0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
字节2 | 长度LSB(3) | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
字节3 | 'a'(0x61) | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
字节4 | '/'(0x2F) | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
字节5 | 'b'(0x62) | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 |
主题名称 | |||||||||
字节6 | 长度MSB(0) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
字节7 | 长度LSB(3) | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
字节8 | 'c'(0x63) | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 |
字节9 | '/'(0x2F) | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
字节10 | 'd'(0x64) | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
响应
服务器向客户端发送UNSUBACK以响应anUNSUBSCRIBE消息。
3.11。UNSUBACK - 取消订阅确认
UNSUBACK消息由服务器发送到客户端确认收到的消息退订信息。
固定标题
下表显示了固定的标头格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(11) | DUP标志 | QoS级别 | 保留 | ||||
| 1 | 0 | 1 | 1 | X | X | X | X |
字节2 | 剩余长度(2) | |||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
QoS级别
不曾用过。
DUP标志
不曾用过。
保留标志
不曾用过。
剩余长度
变量头的长度(2个字节)。
变量头
变量头包含的消息ID退订正在确认的消息。下表显示了变量头的格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息ID MSB | |||||||
字节2 | 消息ID LSB |
有效载荷
没有有效载荷。
3.12。PINGREQ - PING请求
PINGREQ消息是“你还活着吗?” 从连接的客户端发送到服务器的消息。
看到保持活着的计时器更多细节。
固定标题
下表显示了固定的标头格式。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(12) | DUP标志 | QoS级别 | 保留 | ||||
| 1 | 1 | 0 | 0 | X | X | X | X |
字节2 | 剩余长度(0) | |||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
不使用DUP,QoS和RETAIN标志。
变量头
没有变量头。
有效载荷
没有有效载荷。
响应
对PINGREQ消息的响应是PINGRESP消息。
3.13。PINGRESP - PING响应
PINGRESP消息是服务器发送给的消息PINGREQ消息并表示“是的,我还活着”。
看到保持活着的计时器更多细节。
固定标题
下表显示了固定的标头格式:
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(13) | DUP标志 | QoS级别 | 保留 | ||||
| 1 | 1 | 0 | 1 | X | X | X | X |
字节2 | 剩余长度(0) | |||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
不使用DUP,QoS和RETAIN标志。
有效载荷
没有有效载荷。
变量头
没有变量头。
3.14。DISCONNECT - 断开通知
DISCONNECT消息从客户端发送到服务器,表示它将要关闭其TCP / IP连接。这样可以实现干净的断开,而不仅仅是掉线。
如果客户端已连接到清洁会议标志设置,然后将丢弃有关客户端的所有先前维护的信息。
接收到DISCONNECT后,服务器不应依赖客户端来清除TCP / IP连接。
固定标题
固定标题格式如下表所示。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节1 | 消息类型(14) | DUP标志 | QoS级别 | 保留 | ||||
| 1 | 1 | 1 | 0 | X | X | X | X |
字节2 | 剩余长度(0) | |||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
DISCONNECT消息中不使用DUP,QoS和RETAIN标志。
有效载荷
没有有效载荷。
变量头
没有变量头。
4.流动
4.1。服务质量水平和流量
MQTT根据服务质量(QoS)中定义的级别传递消息。级别描述如下:
QoS级别0:最多一次交付
根据底层TCP / IP网络的最佳努力传递消息。不期望响应,并且协议中没有定义重试语义。消息一次到达服务器或根本不到达服务器。
下表显示了QoS级别0协议流程。
客户 | 消息和方向 | 服务器 |
QoS = 0 | 发布 | 行动:向订阅者发布消息 |
QoS级别1:至少一次交付
服务器接收消息由PUBACK消息确认。如果通信链路或发送设备发现故障,或者在指定的时间段后未收到确认消息,则发送方将重新发送消息标头中设置的DUP位的消息。消息至少到达服务器一次。SUBSCRIBE和UNSUBSCRIBE消息都使用QoS级别1。
QoS级别为1的消息在消息头中具有消息ID。
下表显示了QoS级别1协议流程。
客户 | 消息和方向 | 服务器 |
QoS = 1 行动:存储消息 | 发布 | 操作:
|
行动:丢弃消息 | PUBACK |
|
如果客户端未收到PUBACK消息(在应用程序中定义的时间段内,或者如果检测到故障并且重新启动通信会话),则客户端可以重新发送发布设置了DUP标志的消息。
当它从客户端收到重复消息时,服务器将消息重新发布给订户,并发送另一个PUBACK消息。
QoS级别2:完全一次交付
QoS级别1之上的附加协议流程确保不会将重复的消息传递到接收应用程序。这是最高级别的传递,用于不接受重复邮件的情况。网络流量有所增加,但由于消息内容的重要性,通常可以接受。
QoS级别为2的消息在消息头中具有消息ID。
下表显示了QoS级别2协议流程。有两种语义可用于接收方应如何处理PUBLISH流。它们影响流程中消息可供订户使用的点。语义的选择是特定于实现的,并不影响QoS 2级流的保证。
客户 | 消息和方向 | 服务器 |
QoS = 2 行动:存储消息 | 发布 | 行动:存储消息 要么 操作:
|
| PUBREC | 消息ID = x |
消息ID = x | PUBREL | 操作:
要么 行动:删除邮件ID |
行动:丢弃消息 | PUBCOMP | 消息ID = x |
如果检测到故障,或者在定义的时间段之后,则从最后未确认的协议消息重试协议流程; PUBLISH或PUBREL。看到邮件传递重试更多细节。附加协议流程确保仅将消息传递给订户一次。
QoS级别1和2的假设
在任何网络中,设备或通信链路都可能失败。如果发生这种情况,链接的一端可能不知道另一端正在发生什么; 这些被称为怀疑在这些情况下,必须对消息传递中涉及的设备和网络的可靠性做出假设。
MQTT假设客户端和服务器通常是可靠的,并且通信通道更可能不可靠。如果客户端设备发生故障,则通常是灾难性故障,而不是瞬态故障。从设备恢复数据的可能性很低。一些设备具有非易失性存储,例如闪存ROM。在客户端设备上提供更持久的存储保护了来自某些故障模式的最关键数据。
除了通信链路的基本故障之外,故障模式矩阵变得复杂,导致比MQTT的规范可以处理的场景更多。
4.2。邮件传递重试
尽管TCP通常保证数据包的传递,但在某些情况下可能无法接收到MQTT消息。对于期望响应的MQTT消息(QoS> 0 PUBLISH,PUBREL,SUBSCRIBE,UNSUBSCRIBE),如果未在内部收到响应在某段时间内,发件人可能会重试发送。发件人应该设置DUP酒吧消息。
重试超时应该是可配置选项。但是,必须注意确保消息传递在发送时不会超时。例如,通过慢速网络发送大小的消息自然需要比快速网络上的小消息更长的时间。反复重试超时消息通常会使事情变得更糟,因此应该使用在多次重试中增加超时值的策略。
当客户端重新连接时,如果未标记干净的会议,客户端和服务器都应该重新发送以前的任何正在进行的消息。
除了“重新连接”重试行为之外,客户端不需要重新发送消息。但是,经纪人应该重试任何未经确认的消息。
4.3。消息排序
消息排序可能受到许多因素的影响,包括许多正在进行的操作发布流客户端允许客户端是单线程还是多线程。出于讨论的目的,假设客户端在数据包被写入网络和从网络读取的点处是单线程的。
对于提供有关消息排序的任何保证的实现,必须确保消息传递流的每个阶段按照它们的启动顺序完成。例如,在一系列QoS级别2流中,PUBREL流必须以与originalPUBLISH流相同的顺序发送:
客户 | 消息和方向 | 服务器 |
| 发布1 |
|
| PUBREC 1 |
|
| PUBREL 1 |
|
| PUBREC 3 |
|
| PUBREL 2 |
|
| PUBCOMP 1 |
|
| PUBREL 3 |
|
| PUBCOMP 2 |
|
允许的飞行中消息的数量也会对可以进行的保证类型产生影响:
- 在飞行窗口为1的情况下,每个交付流程在下一个开始之前完成。这种保证消息按照提交的顺序提供。
- 在飞行窗口大于1的情况下,只能在QoS级别保证消息排序。
附录A - 主题通配符
订阅可能包含特殊字符,允许您一次订阅多个主题。
主题级别分隔符用于将结构引入主题,因此可以在主题中为此目的指定。多级别会员卡和单级通配符可用于订阅,但消息的发布者不能在主题中使用它们。
主题级别分隔符
正斜杠(/)用于分隔主题树中的每个级别,并为主题空间提供分层结构。当订阅者指定的主题中遇到两个通配符时,主题级别分隔符的使用很重要。
多级通配符
数字符号(#)是一个通配符,可以匹配主题中的任意数量的级别。例如,如果您订阅金融/股票/ IBM /#,您收到有关这些主题的消息:
多级通配符可以表示零个或多个级别。因此,金融/#也可以匹配单数金融,哪里#代表零水平。在此上下文中,主题级别分隔符无意义,因为没有要分隔的级别。
多级通配符只能单独指定或在主题级别分隔符旁边指定。因此,#和金融/#都有效,但是金融#无效。多级通配符必须是主题树中使用的最后一个字符。例如,金融/#是有效的但是金融/#/ closingprice无效。
单级通配符
加号(+)是一个通配符,只匹配一个主题级别。例如,金融/股票/ +火柴金融/股票/ IBM和金融/股票/ XYZ, 但不是金融/股票/ IBM / closingprice。此外,因为单级通配符只匹配单个级别,金融/ +不匹配金融.
单级通配符可以在主题树中的任何级别使用,也可以与多级通配符结合使用。它必须在主题级别分隔符旁边使用,除非它自己指定。因此,+和金融/ +都有效,但是金融+无效。单级通配符可以在主题树的末尾或主题树中使用。例如,金融/ +和金融/ + / IBM都是有效的。
主题语义和用法
构建应用程序时,主题树的设计应考虑主题名称语法和语义的以下原则:
- 主题必须至少有一个字符长。
- 主题名称区分大小写。例如,账户和帐号是两个不同的主题。
- 主题名称可以包含空格字符。例如,应付账款是一个有效的主题。
- 前导“/”创建一个独特的主题。例如,/金融不同于金融./金融匹配“+ / +”和“/ +”,但不匹配“+”。
- 不要包含空字符(Unicode
\x0000
)在任何主题中。
以下原则适用于topictree的构建和内容:
- 长度限制为64k,但在此范围内,主题树中的级别数量没有限制。
- 可以有任意数量的根节点; 也就是说,可以有任意数量的主题树。