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