MQTT V3.1.1 协议 规范

目录

1.简介

1.1术语

​1.2 数据表示

1.2.1 位

1.2.2整数数据值

1.2.3 UTF-8编码的字符串

2 MQTT控制包格式

2.1 MQTT控制包的结构

2.2 固定报头

2.2.1 MQTT控制报文类型

2.2.2 标志

2.2.3剩余长度

2.3 可变报头

2.3.1 数据包标识符

2.4 有效载荷

3 MQTT控制包

3.1 CONNECT –客户端请求与服务器的连接 

3.1.1 固定头

3.1.2 可变头

3.1.3 有效载荷

3.1.4 应答

3.2 CONNACK –确认连接请求

3.2.1 Fixed header

3.2.2 Variable header

3.2.3有效载荷

3.3 PUBLISH – 发布消息

3.3.1 Fixed header

3.3.2  Variable header

3.3.3 Payload

3.3.4 Response

3.3.5 Actions

3.4 PUBACK –发布确认

3.4.1 Fixed header

3.4.2 Variable header

3.4.3 Payload

3.4.4 Actions

3.5 PUBREC –发布已接收(QoS 2已发布,第1部分)

3.5.1 Fixed header

3.5.2 Variable header

3.5.3 Payload

3.5.4 Actions

3.6 PUBREL –发布发布(已收到QoS 2发布,第2部分)

3.6.1 Fixed header

3.6.2 Variable header

3.6.3 Payload

3.6.4 Actions

3.7 PUBCOMP –完成发布(已收到QoS 2发布,第3部分)

 3.7.1 Fixed header

3.7.2 Variable header

3.7.3 Payload

3.7.4 Actions

3.8 SUBSCRIBE-订阅主题

 3.8.1 Fixed header

3.8.2 Variable header

 3.8.3 Payload

3.8.4 Response

3.9 SUBACK –订阅确认

3.9.1 Fixed header

3.9.2 Variable header

3.9.3 Payload

3.10 UNSUBSCRIBE–退订主题

3.10.1 Fixed header

3.10.2 Variable header

3.10.3 Payload

3.10.4 Response

3.11 UNSUBACK-取消订阅确认

3.11.1 Fixed header

3.11.2 Variable header

3.11.3 Payload

3.12 PINGREQ – PING请求

3.12.1 Fixed header

3.12.2 Variable header

3.12.3 Payload

 3.12.4 Response

3.13 PINGRESP – PING响应

3.13.1 Fixed header

3.13.2 Variable header

3.13.3 Payload

3.14 DISCONNECT –断开通知

3.14.1 Fixed header

3.14.2 Variable header

3.14.3 Payload

3.14.4 Response

4   Operational behavior

4.1 Storing state

4.1.1非规范说明示例

4.2网络连接

4.3服务质量级别和协议流

4.3.1 QoS 0: At most once delivery

4.3.2 QoS 1: At least once delivery

4.3.3 QoS 2: Exactly once delivery

4.4 Message delivery retry(消息重传)

4.5 Message receipt(消息回执)

4.6 Message ordering(消息排序)

4.7 Topic Names and Topic Filters(主题名称和主题过滤器)

4.7.1 Topic wildcards(主题通配符)

4.7.2  Topics beginning with $(以$开头的主题)

4.7.3 Topic semantic and usage(主题的语法和用法)

4.8 Handling errors(错误处理)

5 安全

5.1 简介

5.2 MQTT解决方案:安全性和认证

5.3 轻量级加密和受约束的设备

5.4实施说明

5.4.1 服务器对客户端的身份验证

5.4.2 服务器对客户端的授权

5.4.3 客户端对服务器的身份验证

5.4.4 应用消息和控制包的完整性

5.4.5 应用消息和控制包的私有性

5.4.6 不可拒绝的消息传输

5.4.7 检测客户端和服务器的危害

5.4.8 检测异常行为

5.4.9 其他安全考虑

5.4.10 Use of SOCKS

5.4.11安全配置文件

6   Using WebSocket as a network transport

6.1 IANA注意事项

7 一致性

7.1一致性指标

7.1.1 MQTT服务器

7.1.2 MQTT客户端

8.  Wirshark 抓包截图


1.简介

1.1术语

在本规范中,关键字“必须”,“不得”,“必须”,“应”,“应不”,“应”,“不应”,“建议”,“可以”和“可选”是 如IETF RFC 2119 [RFC2119]中所述进行解释。

网络连接(Network Connection):

由MQTT使用的基础传输协议提供的构造。

  • 将客户端连接到服务器。
  • ·它提供了在两个方向上发送有序的无损字节流的方法。

有关示例,请参见第4.2节。

应用信息(Application Message

MQTT协议通过网络为应用程序承载的数据。当MQTT传输应用程序消息时,它们具有关联的服务质量和主题名称。

客户端Client):

使用MQTT的程序或设备。客户端始终建立与服务器的网络连接。它可以

  • 发布其他客户端可能感兴趣的应用程序消息。
  • 订阅以请求有兴趣接收的应用程序消息。
  • 退订以删除对应用程序消息的请求。
  • 断开与服务器的连接。

服务器(Server

一种程序或设备,充当发布应用程序消息的客户端和进行订阅的客户端之间的中介。服务器

  • 接受来自客户端的网络连接。
  • 接受客户端发布的应用程序消息。
  • 处理来自客户端的订阅和取消订阅请求。
  • 转发与客户端订阅匹配的应用程序消息。

订阅(Subscription

订阅包括主题过滤器和最大QoS。订阅与单个会话关联。一个会话可以包含多个订阅。会话中的每个订阅都有一个不同的主题过滤器。

主题名称(Topic Name)

附加到应用程序消息的标签,该标签与服务器已知的订阅相匹配。服务器将应用程序消息的副本发送给具有匹配订阅的每个客户端。

主题过滤器(Topic Filter)

订阅中包含的一种表达,表示对一个或多个主题感兴趣。主题过滤器可以包含通配符。

会话(Session)

客户端和服务器之间的状态交互。某些会话的持续时间仅与网络连接的时间相同,而其他会话则可以跨越客户端和服务器之间的多个连续的网络连接。

MQTT控制数据包(MQTT Control Packet:)

通过网络连接发送的信息包。 MQTT规范定义了十四种不同类型的控制包,其中一种(发布包)用于传达应用消息。

 

MQTT V3.1.1 协议 规范_第1张图片

1.2 数据表示

1.2.1 位

字节中的位标记为7到0。位号7是最高有效位,最低位是0。

1.2.2整数数据值

整数数据值,16位按大端顺序:

高位字节位于低位字节之前。 这意味着在网络上将16位字表示为最高有效字节(MSB),然后是最低有效字节(LSB)。

1.2.3 UTF-8编码的字符串

稍后描述的控制包中的文本字段被编码为UTF-8字符串。 UTF-8 [RFC3629]是Unicode [Unicode]字符的有效编码,可优化ASCII字符的编码以支持基于文本的通信。

这些字符串中的每个字符串都有两个字节的长度字段作为前缀,该字段给出了UTF-8编码的字符串本身的字节数,如下图1.1所示。 因此,在这些UTF-8编码的字符串组件之一中可以传递的字符串的大小受到限制。 您不能使用编码超过65535个字节的字符串。

除非另有说明,否则所有UTF-8编码的字符串的长度都可以在0到65535字节之间。

图1.1 Structure of UTF-8 encoded strings

Bit

7

6

5

4

3

2

1

0

byte 1

String length MSB

byte 2

String length LSB

byte 3 ….

UTF-8 Encoded Character Data, if length > 0.

UTF-8编码的字符串中的字符数据必须按照Unicode规范[Unicode]的规定,采用格式正确的UTF-8,并在RFC 3629 [RFC3629]中进行重述。 特别是,此数据不得包含U + D800和U + DFFF之间的代码点编码。 如果服务器或客户端收到包含格式错误的UTF-8的控制包,则必须关闭网络连接。

UTF-8编码的字符串不得包含空字符U + 0000的编码。 如果接收方(服务器或客户端)接收到包含U + 0000的控制包,则必须关闭网络连接

数据不应包含下面列出的Unicode [Unicode]代码点的编码。 如果接收方(服务器或客户端)接收到包含任何接收方的控制包,则可以关闭网络连接

U + 0001..U + 001F控制字符

U + 007F..U + 009F控制字符

Unicode规范[Unicode]中定义的代码点为非字符(例如U + 0FFFF)

UTF-8编码的序列0xEF 0xBB 0xBF始终应解释为表示U + FEFF(“零宽度无间断空格”),无论它出现在字符串中什么地方,并且一定不要被数据包接收器跳过或剥离。

2 MQTT控制包格式

2.1 MQTT控制包的结构

MQTT协议通过以定义的方式交换一系列MQTT控制包来工作。 本节介绍这些数据包的格式。

MQTT控制包最多由三部分组成,始终按以下顺序排列,如图2.1-MQTT控制包的结构所示。

Figure 2.1 – Structure of an MQTT Control Packet
固定报头(Fixed header), present in all MQTT Control Packets
可变报头(Variable header), present in some MQTT Control Packets
有效载荷(Payload), present in some MQTT Control Packets

2.2 固定报头

每个MQTT控制包都包含一个固定的报头。 图2.2-固定标头格式说明了固定标头格式。

图2.2 固定报文头格式
Bit 7 6 5 4 3 2 1 0

byte 1

MQTT 控制报文的类型

控制报文类型的标志位

byte 2…

剩余长度

2.2.1 MQTT控制报文类型

位置:字节1,位7-4。

表示为4位无符号值的值在表2.1-控制包类型中列出。

Table 2.1 - Control packet types

Reserved

0

禁止

保留

CONNECT

1

Client to Server

客户端请求连接服务器

CONNACK

2

Server to Client

连接报文确认

PUBLISH

3

Client to Server

          or

Server to Client

发布消息

PUBACK

4

Client to Server

          or

Server to Client

消息发布收到确认(QoS1)

PUBREC

5

Client to Server

          or

Server to Client

发布收到 (QoS2)

PUBREL

6

Client to Server

          or

Server to Client

发布释放(QoS2)

PUBCOMP

7

Client to Server

          or

Server to Client

发布完成(QoS2)

SUBSCRIBE

8

Client to Server

客户端订阅请求

SUBACK

9

Server to Client

订阅请求报文确认

UNSUBSCRIBE

10

Client to Server

客户端取消订阅请求

UNSUBACK

11

Server to Client

取消订阅报文确认

PINGREQ

12

Client to Server

心跳请求

PINGRESP

13

Server to Client

心跳响应

DISCONNECT

14

Client to Server

客户端断开连接

Reserved

15

Forbidden

系统保留

2.2.2 标志

固定报头中字节1的其余[3-0]位包含特定于每种MQTT控制数据包类型的标志,如下面的表2.2-标志位中所列。

如果在表2.2-标志位中将标志位标记为“保留”,则保留该标志位以备将来使用,并且必须将其设置为该表[MQTT-2.2.2-1]中列出的值。 如果收到无效标志,则接收方必须关闭网络连接[MQTT-2.2.2-2]。 有关处理错误的详细信息,请参见第4.8节。

Table 2.2 - Flag Bits

Control Packet

Fixed header flags

Bit 3

Bit 2

Bit 1

Bit 0

CONNECT

Reserved

0

0

0

0

CONNACK

Reserved

0

0

0

0

PUBLISH

Used in MQTT 3.1.1

DUP1

QoS2

QoS2

RETAIN3

PUBACK

Reserved

0

0

0

0

PUBREC

Reserved

0

0

0

0

PUBREL

Reserved

0

0

1

0

PUBCOMP

Reserved

0

0

0

0

SUBSCRIBE

Reserved

0

0

1

0

SUBACK

Reserved

0

0

0

0

UNSUBSCRIBE

Reserved

0

0

1

0

UNSUBACK

Reserved

0

0

0

0

PINGREQ

Reserved

0

0

0

0

PINGRESP

Reserved

0

0

0

0

DISCONNECT

Reserved

0

0

0

0

DUP =重复发送发布控制包

QoS =发布服务质量

RETAIN = PUBLISH保留标志

有关发布控制包中DUP,QoS和RETAIN标志的说明,请参见第3.3.1节。

注:事实上,除了PUBLISH类型报文以外,其他报文的标志位均为系统保留,PUBLISH 报文的第一字节bit3 是控制报文的重复分发标志(DUP),bit1-bit2 是服务质量等级,bit0 是PUBLISH 报文的保留标志,用于标识PUBLISH 是否保留,当客户端发送一个PUBLISH 消息到服务器,如果保留标识位置1,那么服务器应该保留这条消息,当一个新的订阅者订阅这个主题的时候,最后保留的主题消息应被发送到新订阅的用户。

2.2.3剩余长度

位置:从字节2开始。

剩余长度是当前数据包中剩余的字节数,包括变量头和有效载荷中的数据。 剩余长度不包括用于编码剩余长度的字节。

剩余长度使用可变长度编码方案进行编码,该方案使用单个字节表示最大127的值。较大的值按以下方式处理。 每个字节的最低有效七位对数据进行编码,而最高有效位用于指示表示中有后续字节。 因此,每个字节编码128个值和一个“连续位”。 剩余长度字段中的最大字节数为4。

MQTT V3.1.1 协议 规范_第2张图片

2.3 可变报头

某些类型的MQTT控制包包含可变报头组件。 它位于固定标头和有效负载之间。 可变报头的内容取决于数据包类型。 可变报头的数据包标识符字段在几种数据包类型中是常见的。 

2.3.1 数据包标识符

MQTT V3.1.1 协议 规范_第3张图片

许多控制数据包类型的可变报头组件都包含一个2字节的数据包标识符字段。 这些控制数据包是PUBLISH(QoS> 0),PUBACK,PUBREC,PUBREL,PUBCOMP,SUBSCRIBE,SUBACK,UNSUBSCRIBE和UNSUBACK。

SUBSCRIBE,UNSUBSCRIBE和PUBLISH(在QoS> 0的情况下)控制分组必须包含一个非零的16位分组标识符[MQTT-2.3.1-1]。

每次客户发送一个新的这些类型之一的数据包,它必须给它分配一个当前未使用的数据包标识符[MQTT-2.3.1-2]。

如果客户端重新发送一个特定的控制包,则它必须在该包的后续重新发送中使用相同的包标识符。 在客户端处理了相应的确认数据包后,数据包标识符就可以重用。 在QoS 1 PUBLISH的情况下,这是对应的PUBACK; 在QoS 2的情况下,它是PUBCOMP。

对于SUBSCRIBE或UNSUBSCRIBE,它是对应的SUBACK或UNSUBACK [MQTT-2.3.1-3]。

当服务器发送QoS> 0 [MQTT-2.3.1-4]的发布消息时,这些条件也适用于服务器。 

如果发布的包的QoS值设置为0 [MQTT-2.3.1-5],则它绝对不能包含包标识符。

PUBACK,PUBREC或PUBREL数据包必须包含与最初发送的PUBLISH数据包相同的数据包标识符[MQTT-2.3.1-6]。

同样,SUBACK和UNSUBACK必须包含分别在相应的SUBSCRIBE和UNSUBSCRIBE数据包[MQTT-2.3.1-7]中使用的数据包标识符。

表2.5-包含数据包标识符的控制数据包中列出了需要数据包标识符的控制数据包。

MQTT V3.1.1 协议 规范_第4张图片

客户端和服务器彼此独立地分配分组标识符。 结果,客户端服务器对可以使用相同的数据包标识符参与并发消息交换。

例子:

客户端可以发送带有数据包标识符0x1234的PUBLISH数据包,然后在接收到发送的PUBLISH消息的PUBACK之前,从其服务器接收另一个带有Packet Identifier 0x1234的PUBLISH消息。

2.4 有效载荷

如第3章所述,某些MQTT控制数据包包含有效载荷作为数据包的最后部分。对于发布数据包,这是应用程序消息。 表2.6-包含有效负载的控制包列出了需要有效负载的控制包。 

MQTT V3.1.1 协议 规范_第5张图片

3 MQTT控制包

3.1 CONNECT –客户端请求与服务器的连接 

客户端与服务器建立网络连接后,从客户端发送至服务器的第一个数据包必须为CONNECT数据包[MQTT-3.1.0-1]。

客户端只能通过网络连接发送一次CONNECT数据包。 服务器必须处理从客户端发送的第二个CONNECT数据包,作为协议违规,并断开客户端[MQTT-3.1.0-2]的连接。 有关处理错误的信息,请参见第4.8节。

有效负载包含一个或多个编码字段。 它们为客户端指定唯一的客户端标识符,“遗嘱”主题,“遗嘱消息”,“用户名”和“密码”。 除客户端标识符外,其余是可选的,它们的存在是根据变量头中的标志确定的。

3.1.1 固定头

MQTT V3.1.1 协议 规范_第6张图片

剩余长度字段

剩余长度是变量头的长度(10个字节)加上有效负载的长度。 它按照第2.2.3节中所述的方式进行编码。 

3.1.2 可变头

CONNECT数据包的变量头按以下顺序包含四个字段:协议名称,协议级别,连接标志和保持活动。

3.1.2.1 协议名称

MQTT V3.1.1 协议 规范_第7张图片

协议名称是UTF-8编码的字符串,代表协议名称“ MQTT”,大写,如下所示。 字符串,其偏移量和长度将不会在MQTT规范的未来版本中更改。 

如果协议名称不正确,服务器可以断开客户端的连接,或者可以继续按照其他规范处理CONNECT数据包。 在后一种情况下,服务器不得根据本规范[MQTT-3.1.2-1]继续处理CONNECT数据包。

注:数据包检查器(例如防火墙)可以使用协议名称来标识MQTT通信。

3.1.2.2 协议级别

MQTT V3.1.1 协议 规范_第8张图片

8位无符号值,表示客户端使用的协议的修订级别。 协议版本3.1.1的“协议级别”字段的值为4(0x04)。 如果服务器[MQTT-3.1.2-2]不支持协议级别,服务器必须以CONNACK返回码0x01(不可接受的协议级别)响应CONNECT数据包,然后,断开客户端的连接。 

3.1.2.3 连接标志

连接标志字节包含许多参数,这些参数指定MQTT连接的行为。 它还指示有效载荷中字段的存在或不存在。

MQTT V3.1.1 协议 规范_第9张图片

服务器必须确认CONNECT控制包中的保留标志设置为零,如果不为零,则断开客户端的连接[MQTT-3.1.2-3]。

3.1.2.4 清除会话

位置:连接标志字节的位1。

该位指定会话状态的处理。

客户端和服务器可以存储会话状态,以使可靠的消息传递能够在一系列网络连接中继续进行。 该位用于控制会话状态的生存期。

如果CleanSession设置为0,则服务器务必根据当前会话的状态(由客户端标识符标识)恢复与客户端的通信。 如果没有与客户端标识符相关的会话,则服务器必须创建一个新的会话。 客户端和服务器断开连接后,客户端和服务器必须存储会话[MQTT-3.1.2-4]。

在将CleanSession设置为0的会话断开连接后,服务器务必将与断开连接时客户端具有的所有订阅相匹配的其他QoS 1和QoS 2消息作为会话状态[MQTT-3.1.2-5]。 它还可以存储满足相同条件的QoS 0消息。

如果CleanSession设置为1,则客户端和服务器务必丢弃任何先前的会话并开始一个新的会话。 该会话持续到网络连接。 与该会话相关的状态数据不得在任何后续会话[MQTT-3.1.2-6]中重用。

客户端中的会话状态包括:

  • ·已发送到服务器但尚未完全确认的QoS 1和QoS 2消息。
  • ·已从服务器收到但未完全确认的QoS 2消息。

服务器中的会话状态包括:

  • ·会话的存在,即使会话的其余状态为空。
  • ·客户的订阅。
  • ·已发送到客户端但尚未完全确认的QoS 1和QoS 2消息。
  • ·QoS 1和QoS 2消息等待传输到客户端。
  • ·已经从客户端收到但尚未完全确认的QoS 2消息。
  • ·(可选)QoS 0消息等待传输到客户端。

保留的消息不构成服务器中会话状态的一部分,在会话结束时不得删除它们[MQTT-3.1.2.7]。

3.1.2.5 Will Flag (遗嘱标志)

位置:连接标志的第2位。

如果将Will Flag设置为1,则表示如果接受了连接请求,则Will消息必须存储在服务器上并与网络连接关联。 除非网络在收到DISCONNECT数据包[MQTT-3.1.2-8]后删除了Will消息,否则必须在随后关闭网络连接时发布Will消息。

发布遗嘱消息的情况包括但不限于:

  • 服务器检测到 I/O 错误或网络故障。
  • 客户端在保持活动时间内无法通信。
  • 客户端未先发送DISCONNECT数据包即可关闭网络连接。
  • 由于协议错误,服务器关闭了网络连接。

如果将Will Flag设置为1,则服务器将使用Connect Flag中的Will QoS和Will Retain字段,并且有效负载中必须存在Will Topic和Will Message字段[MQTT-3.1.2-9]。

一旦发布了Will消息,或者服务器从客户端[MQTT-3.1.2-10]接收到DISCONNECT数据包,则必须将Will消息从服务器中的已存储会话状态中删除。

如果将Will标志设置为0,则必须将连接标志中的Will QoS和Will Retain字段设置为零,并且在有效载荷[MQTT-3.1.2-11]中不得出现Will Topic和Will Message字段。

如果将Will标志设置为0,则在此网络连接结束时[MQTT-3.1.2-12]不得发布Will消息。

服务器应该及时发布遗嘱消息。 在服务器关闭或失败的情况下,服务器可以将Will Messages的发布推迟到随后的重启。 如果发生这种情况,则在服务器出现故障与发布Will消息之间可能会有延迟。

3.1.2.6 Will QoS(遗嘱消息服务质量等级)

位置:连接标志的第4位和第3位。

这两位指定发布遗嘱消息时要使用的QoS级别。

如果将Will Flag设置为0,则Will QoS必须设置为0(0x00)[MQTT-3.1.2-13]。

如果将Will Flag设置为1,则Will QoS的值可以为0(0x00),1(0x01)或2(0x02)。 不得为3(0x03)[MQTT-3.1.2-14]。

3.1.2.7 Will Retain(遗嘱保留)

位置:连接标志的第5位。

该位指定在发布遗嘱消息时是否保留该遗嘱消息。

如果Will flag 设置为0,则Will Retain 务必设置为0 [MQTT-3.1.2-15]。
如果将Will flag 设置为1:
     如果Will Retain设置为0,则服务器必须发布Will消息作为非保留消息[MQTT-3.1.2-16]。
     如果Will Retain设置为1,则服务器必须发布Will消息作为保留消息[MQTT-3.1.2-17]。

3.1.2.8 User Name Flag(用户名标志)

位置:连接标志的第7位。

如果用户名标志设置为0,则有效载荷[MQTT-3.1.2-18]中绝对不能存在用户名。

如果用户名标志设置为1,则用户名必须出现在有效载荷[MQTT-3.1.2-19]中。

3.1.2.9 Password Flag(密码标志)

位置:连接标志字节的第6位。

如果密码标志设置为0,则有效负载[MQTT-3.1.2-20]中绝对不能存在密码。

如果密码标志设置为1,则有效负载[MQTT-3.1.2-21]中必须存在密码。

如果用户名标志设置为0,则密码标志必须设置为0 [MQTT-3.1.2-22]。

3.1.2.10 Keep Alive(保持连接)

MQTT V3.1.1 协议 规范_第10张图片

保持活动状态是以秒为单位的时间间隔。 16位表示,它是客户端完成发送一个控制数据包的时间点与开始发送下一个控制数据包的时间之间允许的最大时间间隔。 客户端有责任确保发送的控制数据包之间的间隔不超过“保持活动”值。 在没有发送任何其他控制分组的情况下,客户端必须发送PINGREQ报文[MQTT-3.1.2-23]。

客户端可以随时发送PINGREQ,而无需考虑“保持活动”值,并可以使用PINGRESP来确定网络和服务器是否正常工作。

如果“保持活动”值不为零,并且服务器在“保持活动”时间的一半时间周期内未收到来自客户端的控制包,则它必须断开与客户端的网络连接,就像网络出现故障一样[MQTT-3.1.2-24。

如果客户端在发送PINGREQ后的合理时间内未收到PINGRESP数据包,则应关闭与服务器的网络连接。

保持活动值为零(0)具有关闭保持活动机制的作用。 这意味着,在这种情况下,不需要服务器以不活动为由断开客户端连接。请注意,无论该客户端提供的“保持活动”值如何,都允许服务器随时断开其确定为不活动或无响应的客户端的连接。

3.1.2.11 可变标头示例

MQTT V3.1.1 协议 规范_第11张图片

3.1.3 有效载荷

CONNECT数据包的有效负载包含一个或多个带前缀的字段,这些字段的存在由变量头中的标志确定。 这些字段(如果存在)必须按客户端标识符,主题,遗嘱消息,用户名,密码[MQTT-3.1.3-1]的顺序显示。

3.1.3.1 Client Identifier (客户端标识符)

客户端标识符(ClientId)标识服务器的客户端。 每个连接到服务器的客户端都有一个唯一的ClientId。 客户端和服务器必须使用ClientId来识别它们与客户端和服务器之间的MQTT会话有关的状态[MQTT-3.1.3-2]。

客户端标识符(ClientId)必须存在,并且必须是CONNECT数据包有效载荷[MQTT-3.1.3-3]中的第一个字段。

ClientId必须是第1.5.3节[MQTT-3.1.3-4]中定义的UTF-8编码的字符串。服务器必须允许长度在1到23个UTF-8编码字节之间且仅包含字符的ClientId。

服务器可以允许包含超过23个编码字节的ClientId。

服务器可以允许客户端提供一个长度为零字节的ClientId,但是如果这样做,则服务器必须将其视为特殊情况,并为该客户端分配一个唯一的ClientId。 然后,它必须处理CONNECT包,就好像客户端已经提供了唯一的ClientId [MQTT-3.1.3-6]。

如果客户端提供了一个零字节的ClientId,则客户端还必须将CleanSession设置为1 [MQTT-3.1.3-7]。

如果客户端提供一个零字节的ClientId且CleanSession设置为0,则服务器务必以CONNACK返回码0x02(拒绝标识符)响应CONNECT数据包,然后关闭网络连接[MQTT-3.1.3-8]。

如果服务器拒绝ClientId,则它必须以CONNACK返回码0x02(拒绝标识符)响应CONNECT数据包,然后关闭网络连接[MQTT-3.1.3-9]。

3.1.3.2 Will Topic(遗嘱主题)

如果将Will Flag设置为1,则Will Topic是有效负载中的下一个字段。 遗嘱主题必须是第1.5.3节[MQTT-3.1.3-10]中定义的UTF-8编码的字符串。

3.1.3.3 Will Message(遗嘱信息)

如果将Will Flag设置为1,则Will Message是有效负载中的下一个字段。 遗嘱信息定义了要发布到遗嘱主题的应用程序消息,如第3.1.2.5节中所述。 该字段由两个字节的长度组成,后跟表示为零个或多个字节的序列的Will消息的有效负载。 长度给出了后续数据中的字节数,并且不包括长度本身占用的2个字节。

3.1.3.4 User Name

如果用户名标志设置为1,则这是有效负载中的下一个字段。 用户名务必是第1.5.3节[MQTT-3.1.3-11]中定义的UTF-8编码的字符串。 服务器可以使用它进行身份验证和授权。

3.1.3.5 Password

如果密码标志设置为1,则这是有效负载中的下一个字段。 密码字段包含0到65535字节的二进制数据,其前缀为两个字节的长度字段,该字段指示二进制数据使用的字节数(它不包括长度字段本身占用的两个字节)。

MQTT V3.1.1 协议 规范_第12张图片

3.1.4 应答

注意,服务器可以在同一TCP端口或其他网络端点上支持多种协议(包括该协议的早期版本)。 如果服务器确定该协议为MQTT 3.1.1,则它将按照以下方式验证连接尝试。

1.如果服务器在建立网络连接后的合理时间内未收到CONNECT数据包,则服务器应关闭连接。

2.服务器必须验证CONNECT数据包是否符合第3.1节的规定,如果不符合[MQTT-3.1.4-1],则在不发送CONNACK的情况下关闭网络连接。

3.服务器可以检查CONNECT数据包的内容是否满足任何进一步的限制,并可以执行身份验证和授权检查。 如果这些检查中的任何一个失败,它应该发送一个适当的带有非零返回码的CONNACK响应,如3.2节所述,并且必须关闭网络连接。

如果验证成功,则服务器将执行以下步骤。

1.如果ClientId代表已经连接到服务器的客户端,则服务器必须断开现有客户端的连接[MQTT-3.1.4-2]。

2.服务器必须执行第3.1.2.4节[MQTT-3.1.4-3]中所述的CleanSession处理。

3.服务器必须用包含零返回码[MQTT-3.1.4-4]的CONNACK包确认CONNECT包。

4.开始传递消息并保持实时监视。

允许客户端在发送CONNECT数据包后立即发送其他控制数据包; 客户端无需等待CONNACK数据包从服务器到达。 如果服务器拒绝CONNECT,则它不得在CONNECT数据包[MQTT-3.1.4-5]之后处理客户端发送的任何数据。

3.2 CONNACK –确认连接请求

CONNACK数据包是服务器响应从客户端收到的CONNECT数据包而发送的数据包。 从服务器发送到客户端的第一个数据包必须是CONNACK数据包[MQTT-3.2.0-1]。

如果客户端在合理的时间内没有收到来自服务器的CONNACK数据包,则客户端应关闭网络连接。 “合理的”时间量取决于应用程序的类型和通信基础结构。

3.2.1 Fixed header

MQTT V3.1.1 协议 规范_第13张图片

剩余长度字段

这是变量头的长度。 对于CONNACK数据包,其值为2。 

3.2.2 Variable header

MQTT V3.1.1 协议 规范_第14张图片

3.2.2.1 Connect Acknowledge Flags 

字节1是“连接确认标志”。 位7-1是保留位,必须设置为0。位0(SP1)是会话存在标志。

3.2.2.2 Session Present

位置:连接确认标志的位0。

如果服务器接受CleanSession设置为1的连接,则除了在CONNACK数据包中设置零返回码[MQTT-3.2.2-1]之外,服务器还必须在CONNACK数据包中将Session Present设置为0。

如果服务器接受CleanSession设置为0的连接,则在Session Present中设置的值取决于Server是否已经为提供的客户端ID存储了Session状态。 如果服务器已存储会话状态,则必须在CONNACK数据包[MQTT-3.2.2-2]中将会话存在设置为1。 如果服务器尚未存储会话状态,则必须在CONNACK数据包中将会话存在设置为0。 这是在CONNACK数据包[MQTT-3.2.2-3]中设置零返回码的补充。

会话存在标志使客户端能够确定客户端和服务器是否对是否已经存储了会话状态具有一致的视图。

一旦会话的初始设置完成,具有存储会话状态的客户端将期望服务器保持其存储会话状态。 如果客户端从服务器收到的Session Present的值与预期不符,则客户端可以选择继续进行会话还是断开连接。 通过断开连接,将Clean Session设置为1并再次断开连接,客户端可以丢弃客户端和服务器上的会话状态。

如果服务器发送包含非零返回码的CONNACK数据包,则必须将会话存在设置为0 [MQTT-3.2.2-4]。

3.2.2.3 Connect Return code

可变报头中的字节2。

表3.1 –连接返回码值中列出了一个字节的无符号连接返回码字段的值。 如果服务器接收到格式正确的CONNECT数据包,但是服务器由于某种原因无法对其进行处理,则服务器应尝试从该表发送包含适当的非零连接返回代码的CONNACK数据包。 如果服务器发送包含非零返回码的CONNACK数据包,则它必须关闭网络连接[MQTT-3.2.2-5]。

MQTT V3.1.1 协议 规范_第15张图片

3.2.3有效载荷

CONNACK数据包没有有效负载。 

3.3 PUBLISH – 发布消息

PUBLISH控制包从客户端发送到服务器,或者从服务器发送到客户端,以传输应用程序消息。

3.3.1 Fixed header

MQTT V3.1.1 协议 规范_第16张图片

3.3.1.1 DUP

位置:字节1,位3。

如果DUP标志设置为0,则表明这是客户端或服务器第一次尝试发送此MQTT PUBLISH数据包。 如果DUP标志设置为1,则表明这可能是较早尝试发送数据包的重新传递。

当客户端或服务器尝试重新发送发布包[MQTT-3.3.1.-1]时,DUP标志必须由客户端或服务器设置为1。 对于所有QoS 0消息[MQTT-3.3.1-2],DUP标志必须设置为0。

服务器将PUBLISH数据包发送给订阅者时,不会传播来自传入PUBLISH数据包的DUP标志的值。 传出的PUBLISH包中的DUP标志独立于传入的PUBLISH包设置,其值必须仅由传出的PUBLISH包是否是重传来确定[MQTT-3.3.1-3]。

3.3.1.2 QoS

位置:字节1,位2-1。

该字段指示用于传递应用消息的保证级别。 下表3.2-QoS定义中列出了QoS级别。

MQTT V3.1.1 协议 规范_第17张图片

PUBLISH数据包绝不能将两个QoS都设置为1。如果服务器或客户端收到两个QoS位都被设置为1的PUBLISH包,则必须关闭网络连接[MQTT-3.3.1-4]。

3.3.1.3 RETAIN (保留)

位置:字节1,位0。

如果RETAIN标志设置为1,则在客户端发送给服务器的PUBLISH数据包中,服务器必须存储应用消息及其QoS,以便可以将其传递给订阅与其主题名称[MQTT-3.3.1-5。 建立新的订阅后,每个匹配主题名称上的最后保留消息(如有)必须发送给订阅者[MQTT-3.3.1-6]。 如果服务器收到RETAIN标志设置为1的QoS 0消息,则它必须丢弃先前为该主题保留的任何消息。 它应该将新的QoS 0消息存储为该主题的新保留消息,但可以选择随时将其丢弃-如果发生这种情况,将没有该主题的保留消息[MQTT-3.3.1-7]。 有关存储状态的更多信息,请参见第4.1节。

当向客户端发送发布数据包时,如果由于客户端[MQTT-3.3.1-8]进行了新的订阅而发送了消息,则服务器必须将RETAIN标志设置为1。 当将PUBLISH数据包发送到客户端时,它必须将RETAIN标志设置为0,因为它与已建立的订阅匹配,无论在接收到的消息中如何设置该标志[MQTT-3.3.1-9]。

服务器将按正常方式处理将RETAIN标志设置为1且负载为零字节的PUBLISH数据包,并通过与主题名称匹配的预订将其发送给客户端。 此外,必须删除具有相同主题名称的任何现有保留消息,并且该主题的任何将来的订阅者都不会收到保留消息[MQTT-3.3.1-10]。 “正常”表示在现有客户端收到的消息中未设置RETAIN标志。 零字节保留消息一定不能作为保留消息存储在服务器[MQTT-3.3.1-11]上。

如果RETAIN标志为0,则在客户端发送给服务器的PUBLISH数据包中,服务器不得存储该消息,并且不得删除或替换任何现有的保留消息[MQTT-3.3.1-12]。

当发布者不定期地发送状态消息时,保留消息很有用。 新订户将收到最新状态。

剩余长度字段
         这是可变报头的长度加上有效负载的长度。

3.3.2  Variable header

变量头按顺序包含以下字段:主题名称,数据包标识符。

3.3.2.1 Topic Name

主题名称标识有效载荷数据发布到的信息通道。

主题名称必须作为PUBLISH Packet Variable标头中的第一个字段出现。 它必须是第1.5.3节中定义的UTF-8编码的字符串[MQTT-3.3.2-1]。

PUBLISH数据包中的主题名称不得包含通配符[MQTT-3.3.2-2]。

服务器发送给订阅客户端的PUBLISH数据包中的主题名称必须根据第4.7节[MQTT-3.3.2-3]中定义的匹配过程与订阅的主题过滤器匹配。 但是,由于允许服务器覆盖主题名称,因此它可能与原始PUBLISH数据包中的主题名称不同。

3.3.2.2 Packet Identifier

数据包标识符字段仅出现在QoS级别为1或2的PUBLISH数据包中。第2.3.1节提供了有关数据包标识符的更多信息。

3.3.2.3 Variable header non normative example

MQTT V3.1.1 协议 规范_第18张图片

3.3.3 Payload

有效负载包含正在发布的应用程序消息。 数据的内容和格式是特定于应用程序的。

有效负载的长度可以通过从固定标头中的“剩余长度”字段中减去变量标头的长度来计算。 PUBLISH数据包包含零长度的有效载荷是有效的。 

3.3.4 Response

PUBLISH数据包的接收者务必根据表3.4-由PUBLISH数据包[MQTT-3.3.4-1]中的QoS确定的预期发布数据包响应。

MQTT V3.1.1 协议 规范_第19张图片

3.3.5 Actions

客户端使用PUBLISH数据包向服务器发送应用消息,以分发给具有匹配订阅的客户端。

服务器使用PUBLISH数据向每个具有匹配订阅的客户端发送应用程序消息。

当客户使用包含通配符的主题过滤器进行订阅时,客户的订阅可能会重叠,以便已发布的邮件可能与多个过滤器匹配。 在这种情况下,服务器必须考虑所有匹配预订的最大QoS [MQTT-3.3.5-1],将消息传递给客户端。 另外,服务器可以传送更多的消息副本,每个附加的匹配订阅一个,并在每种情况下都遵守订阅的QoS。

接收方接收到PUBLISH数据包时的操作取决于第4.3节中描述的QoS级别。

如果服务器实现未授权客户端执行发布; 它无法通知该客户。 它必须根据正常的QoS规则做出肯定的确认,或者关闭网络连接[MQTT-3.3.5-2]。

3.4 PUBACK –发布确认

PUBACK数据包是对QoS级别为1的PUBLISH数据包的响应。

3.4.1 Fixed header

MQTT V3.1.1 协议 规范_第20张图片

剩余长度字段

这是变量头的长度。 对于PUBACK数据包,其值为2。

3.4.2 Variable header

它包含来自正在确认的PUBLISH数据包的数据包标识符。

MQTT V3.1.1 协议 规范_第21张图片

3.4.3 Payload

PUBACK数据包没有有效负载。 

3.4.4 Actions

这在第4.3.2节中有完整描述。

3.5 PUBREC –发布已接收(QoS 2已发布,第1部分)

PUBREC数据包是对具有QoS 2的PUBLISH数据包的响应。它是QoS 2协议交换的第二个数据包。

3.5.1 Fixed header

MQTT V3.1.1 协议 规范_第22张图片

剩余长度字段

这是变量头的长度。 对于PUBREC数据包,其值为2。 

3.5.2 Variable header

变量头包含来自正在确认的PUBLISH数据包的数据包标识符。

MQTT V3.1.1 协议 规范_第23张图片

3.5.3 Payload

PUBREC数据包没有有效负载。

3.5.4 Actions

这在第4.3.3节中有完整描述。

3.6 PUBREL –发布发布(已收到QoS 2发布,第2部分)

PUBREL数据包是对PUBREC数据包的响应。 它是QoS 2协议交换的第三个数据包。 

3.6.1 Fixed header

MQTT V3.1.1 协议 规范_第24张图片

PUBREL控制分组中固定报头的比特3,2,1和0被保留,并且必须分别设置为0,0,1和0。 服务器务必将任何其他值视为格式错误,并关闭网络连接[MQTT-3.6.1-1]。

Remaining Length field

This is the length of the variable header. For the PUBREL Packet this has the value 2.

3.6.2 Variable header

变量头包含与正在确认的PUBREC数据包相同的数据包标识符。

MQTT V3.1.1 协议 规范_第25张图片

 

3.6.3 Payload

The PUBREL Packet has no payload.


3.6.4 Actions

This is fully described in Section 4.3.3.

3.7 PUBCOMP –完成发布(已收到QoS 2发布,第3部分)

PUBCOMP数据包是对PUBREL数据包的响应。 它是QoS 2协议交换的第四个也是最后一个数据包。

 3.7.1 Fixed header

MQTT V3.1.1 协议 规范_第26张图片

Remaining Length field

This is the length of the variable header. For the PUBCOMP Packet this has the value 2.

3.7.2 Variable header

变量头包含与正在确认的PUBREL数据包相同的数据包标识符。

MQTT V3.1.1 协议 规范_第27张图片

3.7.3 Payload

The PUBCOMP Packet has no payload.

3.7.4 Actions

This is fully described in Section 4.3.3.

3.8 SUBSCRIBE-订阅主题

SUBSCRIBE数据包从客户端发送到服务器以创建一个或多个订阅。 每个订阅都会注册客户对一个或多个主题的兴趣。 服务器将PUBLISH数据包发送到客户端,以转发发布到与这些订阅匹配的主题的应用消息。 SUBSCRIBE数据包还(针对每个订阅)指定服务器可以向客户端发送应用消息的最大QoS。

 3.8.1 Fixed header

MQTT V3.1.1 协议 规范_第28张图片

SUBSCRIBE控制包的固定报头的比特3,2,1和0被保留,并且必须分别设置为0,0,1和0。 服务器必须将任何其他值视为格式错误,并关闭网络连接[MQTT-3.8.1-1]。

Remaining Length field

This is the length of variable header (2 bytes) plus the length of the payload.

3.8.2 Variable header

可变报头包含一个数据包标识符。 第2.3.1节提供了有关数据包标识符的更多信息。

3.8.2.1 Variable header non normative example

MQTT V3.1.1 协议 规范_第29张图片

 3.8.3 Payload

SUBSCRIBE数据包的有效负载包含主题过滤器列表,这些列表指示客户端要订阅的主题。 SUBSCRIBE数据包有效载荷中的主题过滤器必须是第1.5.3节[MQTT-3.8.3-1]中定义的UTF-8编码的字符串。 服务器应支持主题过滤器,该过滤器包含第4.7.1节中定义的通配符。 如果选择不支持包含通配符的主题过滤器,则它必须拒绝任何过滤器包含通配符的订阅请求[MQTT-3.8.3-2]。 每个过滤器后跟一个称为“请求的QoS”的字节。 这给出了服务器可以向客户端发送应用程序消息的最大QoS级别。

SUBSCRIBE包的有效载荷必须至少包含一个主题过滤器/ QoS对。 没有有效负载的SUBSCRIBE数据包违反协议[MQTT-3.8.3-3]。 有关处理错误的信息,请参见第4.8节。

所请求的最大QoS字段被编码在每个UTF-8编码的主题名称后面的字节中,并且这些主题过滤器/ QoS对被连续打包。

MQTT V3.1.1 协议 规范_第30张图片

 当前版本的协议未使用“请求的QoS”字节的高6位。 它们保留供将来使用。 如果有效载荷中的保留位中的任何一个不为零,或者QoS不是0.1或2 [MQTT-3-8.3-4],则服务器必须将SUBSCRIBE包视为格式错误并关闭网络连接。

3.8.3.1 Payload non normative example

MQTT V3.1.1 协议 规范_第31张图片

MQTT V3.1.1 协议 规范_第32张图片

3.8.4 Response

当服务器从客户端收到一个SUBSCRIBE数据包时,服务器必须以SUBACK数据包[MQTT-3.8.4-1]作为响应。 SUBACK数据包必须具有与其确认的SUBSCRIBE数据包相同的数据包标识符[MQTT-3.8.4-2]。 

在服务器发送SUBACK数据包之前,允许服务器开始发送与订阅匹配的PUBLISH数据包。

如果服务器收到的SUBSCRIBE数据包包含与现有订阅的主题过滤器相同的主题过滤器,则它必须用新的订阅完全替换现有的订阅。 新订阅中的主题过滤器将与先前订阅中的主题过滤器相同,尽管其最大QoS值可能不同。 必须重新发送与主题过滤器匹配的所有现有保留消息,但不得中断发布流程[MQTT-3.8.4-3]。

如果主题过滤器与任何现有订阅的过滤器都不相同,则会创建一个新的订阅并发送所有匹配的保留消息。

如果服务器接收到包含多个主题过滤器的SUBSCRIBE数据包,则它必须像已接收到多个SUBSCRIBE数据包的序列一样处理该数据包,除了它将它们的响应组合为单个SUBACK响应[MQTT-3.8.4-4]。

服务器发送给客户端的SUBACK包必须包含每个主题过滤器/ QoS对的返回码。 此返回码必须显示为该订阅授予的最大QoS或指示该订阅失败[MQTT-3.8.4-5]。 服务器可能会授予比请求的订户更低的最大QoS。 响应订阅而发送的有效载荷消息的QoS必须是原始发布消息的QoS的最小值和服务器授予的最大QoS。 在原始消息以QoS 1发布且授予的最大QoS为QoS 0的情况下,允许服务器将消息的重复副本发送给订户。MQTT-3.8.4-6。

如果已为特定的主题筛选器向订阅的客户端授予了最大QoS 1,则与该筛选器匹配的QoS 0应用程序消息将以QoS 0传递给客户端。这意味着客户端最多接收到该消息的一个副本。 另一方面,发布到同一主题的QoS 2消息被服务器降级为QoS 1,以便传递给客户端,因此客户端可能会收到消息的重复副本。

如果已向订阅的客户端授予最大QoS 0,则最初发布为QoS 2的应用程序消息可能会在到客户端的跃点上丢失,但是服务器永远不要发送该消息的副本。 发布到同一主题的QoS 1消息在传输到该客户端时可能会丢失或重复。

订阅QoS为2的主题过滤器等效于说“我希望以发布它们的QoS接收与该过滤器匹配的消息”。 这意味着发布者负责确定可以传递消息的最大QoS,但是订阅者可以要求服务器将QoS降级为更适合其使用的QoS。

3.9 SUBACK –订阅确认

服务器将SUBACK数据包发送给客户端,以确认SUBSCRIBE数据包的接收和处理。

SUBACK数据包包含一个返回码列表,这些返回码指定了SUBSCRIBE请求的每个订阅中授予的最大QoS级别。

3.9.1 Fixed header

MQTT V3.1.1 协议 规范_第33张图片

Remaining Length field

This is the length of variable header (2 bytes) plus the length of the payload.

3.9.2 Variable header

可变报头包含来自正在确认的SUBSCRIBE数据包的数据包标识符。 图3.25-下方的可变标头格式说明了可变标头的格式。

MQTT V3.1.1 协议 规范_第34张图片

3.9.3 Payload

有效负载包含返回码列表。 每个返回码对应于已确认的SUBSCRIBE数据包中的主题过滤器。 SUBACK数据包中返回码的顺序必须与SUBSCRIBE数据包[MQTT-3.9.3-1]中主题过滤器的顺序相匹配。

MQTT V3.1.1 协议 规范_第35张图片

允许的返回码:

0x00-成功-最大QoS 0

0x01-成功-最大QoS 1

0x02-成功-最大QoS 2

0x80-失败                                                  

除了0x00、0x01、0x02和0x80以外的SUBACK返回码均保留,不得使用[MQTT-3.9.3-2]。

3.9.3.1 Payload non normative example

MQTT V3.1.1 协议 规范_第36张图片

3.10 UNSUBSCRIBE–退订主题

客户端将UNSUBSCRIBE数据包发送到服务器,以取消订阅主题。

3.10.1 Fixed header

MQTT V3.1.1 协议 规范_第37张图片

UNSUBSCRIBE控制包的固定报头的比特3,2,1和0被保留,并且必须分别设置为0,0,1和0。 服务器务必将任何其他值视为格式错误,并关闭网络连接[MQTT-3.10.1-1]。

Remaining Length field

This is the length of variable header (2 bytes) plus the length of the payload.

3.10.2 Variable header

变量头包含一个数据包标识符。 第2.3.1节提供了有关数据包标识符的更多信息。

MQTT V3.1.1 协议 规范_第38张图片

3.10.3 Payload

UNSUBSCRIBE数据包的有效负载包含客户端希望取消订阅的主题过滤器列表。 UNSUBSCRIBE数据包中的主题过滤器必须是第1.5.3节中定义的,以UTF-8编码的字符串,并连续包装[MQTT-3.10.3-1]。

UNSUBSCRIBE数据包的有效载荷必须至少包含一个主题过滤器。 没有有效载荷的UNSUBSCRIBE数据包违反协议[MQTT-3.10.3-2]。 有关处理错误的信息,请参见第4.8节。 

3.10.3.1 Payload non normative example

MQTT V3.1.1 协议 规范_第39张图片

3.10.4 Response

必须将UNSUBSCRIBE数据包中提供的主题过滤器(无论是否包含通配符)逐个字符地与服务器为客户端保存的当前主题过滤器集进行比较。 如果任何过滤器完全匹配,则将删除其拥有的订阅,否则将不进行任何其他处理[MQTT-3.10.4-1]。 

如果服务器删除订阅:

  •      它必须停止添加任何新消息以传递给客户端[MQTT-3.10.4-2]。
  •      它必须完成已经开始发送给客户端[MQTT-3.10.4-3]的任何QoS 1或QoS 2消息的传递。
  •      它可以继续传递任何缓冲的现有消息,以便传递给客户端。

服务器必须通过发送一个UNSUBACK包来响应UNSUBSUBCRIBE请求。 UNSUBACK数据包必须具有与UNSUBSCRIBE数据包[MQTT-3.10.4-4]相同的数据包标识符。 即使没有删除任何主题订阅,服务器也必须使用UNSUBACK [MQTT-3.10.4-5]进行响应。

如果服务器接收到包含多个主题过滤器的UNSUBSCRIBE数据包,则它必须像对待已接收到多个UNSUBSCRIBE数据包的序列一样处理该数据包,只是它仅发送一个UNSUBACK响应[MQTT-3.10.4-6]。

3.11 UNSUBACK-取消订阅确认

该UNSUBACK包由服务器发送给客户确认收货取消订阅的包的。

3.11.1 Fixed header

MQTT V3.1.1 协议 规范_第40张图片

Remaining Length field

This is the length of the variable header. For the UNSUBACK Packet this has the value 2.

3.11.2 Variable header

可变报头包含正在确认的UNSUBSCRIBE数据包的数据包标识符。

MQTT V3.1.1 协议 规范_第41张图片

3.11.3 Payload

The UNSUBACK Packet has no payload.

3.12 PINGREQ – PING请求

PINGREQ数据包从客户端发送到服务器。 它可以用于:

  •      向服务器指示在没有其他任何控制数据包从客户端发送到服务器的情况下,客户端处于活动状态。
  •      请求服务器做出响应以确认其仍然有效。
  •      练习网络以指示网络连接处于活动状态。

该数据包用于保持活动处理,有关更多详细信息,请参见第3.1.2.10节。

3.12.1 Fixed header

MQTT V3.1.1 协议 规范_第42张图片

3.12.2 Variable header

The PINGREQ Packet has no variable header.

3.12.3 Payload

The PINGREQ Packet has no payload.

 3.12.4 Response

服务器必须响应PINGREQ数据包[MQTT-3.12.4-1]发送PINGRESP数据包。

3.13 PINGRESP – PING响应

服务器响应PINGREQ数据包将PINGRESP数据包发送到客户端。 它指示服务器还活着。

该数据包用于保持活动处理,有关更多详细信息,请参见第3.1.2.10节。

3.13.1 Fixed header

MQTT V3.1.1 协议 规范_第43张图片

 

3.13.2 Variable header

The PINGRESP Packet has no variable header.

3.13.3 Payload

The PINGRESP Packet has no payload.

3.14 DISCONNECT –断开通知

DISCONNECT数据包是从客户端发送到服务器的最终控制数据包。 这表明客户端正在完全断开连接。

3.14.1 Fixed header

MQTT V3.1.1 协议 规范_第44张图片

服务器必须验证保留位是否设置为零,如果保留位不为零,则断开与客户端的连接[MQTT-3.14.1-1]。 

3.14.2 Variable header

The DISCONNECT Packet has no variable header.

3.14.3 Payload

The DISCONNECT Packet has no payload.

3.14.4 Response

发送客户端的DISCONNECT数据包后:

  •      必须关闭网络连接[MQTT-3.14.4-1]。
  •      不得在该网络连接[MQTT-3.14.4-2]上发送更多的控制包。

收到服务器断开连接后:

  •      如第3.1.2.5节[MQTT-3.14.4-3]中所述,必须丢弃与当前连接关联的任何Will Message而不发布它。
  •      如果客户端尚未关闭网络连接,则应关闭网络连接。

4   Operational behavior

4.1 Storing state

客户端和服务器必须存储会话状态才能提供服务质量保证。 客户端和服务器必须在整个会话期间存储会话状态[MQTT-4.1.0-1]。 会话必须至少持续有效的网络连接[MQTT-4.1.0-2]。

保留的消息不构成服务器中会话状态的一部分。 服务器应保留此类消息,直到被客户端删除为止。

 

非规范性说明

  • 客户端和服务器实现的存储功能当然会在容量方面有所限制,并且可能会受管理策略的约束,例如在网络连接之间存储会话状态的最长时间。管理员操作(包括对定义条件的自动响应)可导致丢弃存储的会话状态。这具有终止会话的作用。资源受限或其他操作原因可能会提示这些操作。谨慎评估客户端和服务器的存储功能以确保它们足够。
  • 硬件或软件故障可能会导致客户端或服务器存储的会话状态丢失或损坏。
  • 服务器客户端的正常运行可能意味着由于管理员操作,硬件故障或软件故障而导致存储状态丢失或损坏。管理员操作可以是对定义条件的自动响应。资源受限或其他操作原因可能会提示这些操作。例如,服务器可能基于外部知识确定一条或多条消息不再可以传递给任何当前或将来的客户端。
  • MQTT用户应评估MQTT客户端和服务器实现的存储功能,以确保它们足以满足其需求。

4.1.1非规范说明示例

例如,希望收集电表读数的用户可能会决定他们需要使用QoS 1消息,因为他们需要保护读数免受网络损失,但是,他们可能已经确定电源足够可靠,以至于 客户端和服务器可以存储在易失性内存中,而不会造成太大的丢失风险。

相反,停车收费表支付应用程序提供商可能会决定在任何情况下都不会丢失支付消息,因此他们要求在通过网络传输所有数据之前将所有数据强制写入非易失性存储器。

4.2网络连接

MQTT协议需要基础传输,该传输提供从客户端到服务器以及从服务器到客户端的有序无损字节流。

非规范性评论

如[RFC793]所定义,用于承载MQTT 3.1的传输协议是TCP / IP。 TCP / IP可以用于MQTT 3.1.1。 以下内容也适用:

  • TLS [RFC5246]
  • WebSocket [RFC6455]

非规范性说明

TCP端口88831883已向IANA注册,分别用于MQTT TLS和非TLS通信。

诸如用户数据报协议(UDP)之类的无连接网络传输本身并不适合,因为它们可能会丢失或重新排序数据。

4.3服务质量级别和协议流

MQTT根据此处定义的服务质量(QoS)级别交付应用程序消息。 传递协议是对称的,在下面的描述中,客户端和服务器可以分别充当发送者或接收者的角色。 传递协议仅与将应用程序消息从单个发件人传递到单个接收者有关。 当服务器将一个应用程序消息传递给多个客户端时,每个客户端将被独立对待。 用于将应用程序消息发送到客户端的QoS级别可能与入站应用程序消息的QoS级别不同。

以下各节中的非规范流程图旨在显示可能的实现方法。

4.3.1 QoS 0: At most once delivery

该消息是根据基础网络的功能传递的。 接收方不发送响应,发送方也不进行重试。 消息一次到达接收者或根本不到达。

在QoS 0传递协议中,发送方

  • 必须发送QoS = 0,DUP = 0 [MQTT-4.3.1-1]的PUBLISH数据包。

在QoS 0传递协议中,接收方

  • 在接收到PUBLISH数据包时,接受消息的所有权。

MQTT V3.1.1 协议 规范_第45张图片

4.3.2 QoS 1: At least once delivery

这种服务质量确保了消息至少一次到达接收者。 QoS 1 PUBLISH数据包的变量头中有一个数据包标识符,并由PUBACK数据包确认。 第2.3.1节提供了有关数据包标识符的更多信息。

在QoS 1传递协议中,发件方

  • 每次有新的应用消息要发布时,必须分配一个未使用的包标识符。
  • 必须发送包含此数据包标识符的QoS数据包标识符,DUP = 0的PUBLISH数据包。
  • 必须将PUBLISH数据包视为“未确认”,直到它已从接收方接收到相应的PUBACK数据包。 有关未确认消息的讨论,请参见第4.4节。

一旦发件方收到PUBACK数据包,数据包标识符就可以重用。

请注意,在等待接收确认的同时,允许发件方发送带有不同数据包标识符的其他PUBLISH数据包。

在QoS 1传递协议中,接收方

必须接受来自应用程序消息所有权的,来自输入PUBLISH数据包的,包含数据包标识符的PUBACK数据包响应

发送PUBACK数据包后,接收者务必将包含相同数据包标识符的任何传入PUBLISH数据包视为新的发布,而不论其DUP标志的设置如何。

MQTT V3.1.1 协议 规范_第46张图片

注1:在发送PUBACK之前,不需要接收者完成应用消息的传递。 当其原始发送方收到PUBACK数据包时,应用程序消息的所有权将转移到接收方。 

4.3.3 QoS 2: Exactly once delivery

这是最高的服务质量,适用于既不能丢失消息也不能复制消息的情况。 与该服务质量相关的开销增加了。

QoS 2消息的可变报头中有一个数据包标识符。 第2.3.1节提供了有关数据包标识符的更多信息。 QoS 2 PUBLISH数据包的接收者通过两步确认过程来确认接收。

在QoS 2传递协议中,发送者

  • 当有新的应用消息要发布时,务必分配一个未使用的包标识符。
  • 必须发送包含此数据包标识符的QoS数据包,DUP = 0的PUBLISH数据包。
  • 必须将PUBLISH数据包视为“未确认”,直到它已从接收方接收到相应的PUBREC数据包。 有关未确认消息的讨论,请参见第4.4节。
  • 当它从接收器接收到一个PUBREC包时,必须发送一个PUBREL包。 该PUBREL包必须包含与原始PUBLISH包相同的包标识符。
  • 必须将PUBREL数据包视为“未确认”,直到它已从接收器接收到相应的PUBCOMP数据包为止。
  • 一旦发送了相应的PUBREL数据包,绝不能重新发送PUBLISH。

一旦发件者已收到PUBCOMP数据包,数据包标识符即可重新使用。

请注意,在等待接收确认的同时,允许发件人发送带有不同数据包标识符的其他PUBLISH数据包。

在QoS 2传递协议中,接收方

  •   必须应答一个PUBREC响应,其中包含来自传入PUBLISH数据包的数据包标识符,并已接受了应用消息的所有权。
  •   在接收到对应的PUBREL数据包之前,接收者务必通过发送PUBREC确认具有相同数据包标识符的任何后续PUBLISH数据包。 在这种情况下,它一定不能使重复的信息传递给任何转发的收件人。
  •   必须通过发送包含与PUBREL相同的分组标识符的PUBCOMP分组来响应PUBREL分组。
  •   发送PUBCOMP后,接收者务必将包含该包标识符的任何后续PUBLISH包视为新的发布。

MQTT V3.1.1 协议 规范_第47张图片

注1:在发送PUBREC或PUBCOMP之前,不需要接收者完成应用消息的传递。 当其原始发送方收到PUBREC数据包时,应用程序消息的所有权将转移到接收方。

图4.3显示了有两种方法可以使接收方处理QoS 2。 它们在流程中使消息可用于继续传递的点有所不同。 方法A或方法B的选择是特定于实现的。 只要实施方案正好选择这些方法之一,这就不会影响QoS 2流的保证。 

4.4 Message delivery retry(消息重传)

当客户端在CleanSession设置为0的情况下重新连接时,客户端和服务器都必须使用其原始数据包标识符[MQTT-4.4.0-1]重新发送任何未确认的PUBLISH数据包(其中QoS> 0)和PUBREL数据包。 这是唯一需要重新发送信息的客户端或服务器的情况。

4.5 Message receipt(消息回执)

当服务器获得传入应用程序消息的所有权时,它必须将其添加到具有匹配订阅的那些客户端的会话状态中。 匹配规则在第4.7节[MQTT-4.5.0-1]中定义。

通常情况下,客户会收到响应其创建的订阅的消息。 客户端还可能收到与任何其明确订阅都不匹配的消息。 如果服务器自动为客户端分配了订阅,则会发生这种情况。 客户端还可以在进行UNSUBSCRIBE操作时接收消息。 客户端必须根据适用的QoS规则确认收到的任何发布数据包,无论其是否选择处理包含[MQTT-4.5.0-2]的应用消息。

4.6 Message ordering(消息排序)

在实现本章其他地方定义的协议流时,客户端必须遵循以下规则:

  •      当它重新发送任何PUBLISH数据包时,必须按发送原始PUBLISH数据包的顺序重新发送它们(这适用于QoS 1和QoS 2消息)[MQTT-4.6.0-1]
  •      它必须按照接收到相应的PUBLISH数据包(QoS 1消息)的顺序发送PUBACK数据包[MQTT-4.6.0-2]
  •      它必须按照接收到相应的PUBLISH数据包的顺序(QoS 2消息)发送PUBREC数据包[MQTT-4.6.0-3]
  •      它必须按照接收到相应的PUBREC数据包的顺序(QoS 2消息)发送PUBREL数据包[MQTT-4.6.0-4]

默认情况下,服务器务必将每个主题视为“有序主题”。 它可以提供一种管理或其他机制,以允许将一个或多个主题视为“无序主题” [MQTT-4.6.0-5]。

当服务器处理已发布到有序主题的消息时,向每个订阅者传递消息时,它必须遵循上面列出的规则。 另外,它必须按从任何给定客户端[MQTT-4.6.0-6]收到的顺序,向用户(对于相同的主题和QoS)发送发布数据包。

注:

上面列出的规则可确保在使用QoS 1发布和订阅消息流时,订户接收的每个消息的最终副本都将按照其最初发布的顺序进行,但是可能会导致消息重复重新发送在其后继消息之一之后收到的先前消息。例如,发布者可能以1,2,3,4的顺序发送消息,而订阅者可能以1,2,3,2,3,4的顺序接收消息。

如果客户端和服务器在任何一次都确保不超过一条消息在运行中(通过在确认其前任之前不发送消息),那么以后的任何一条消息都不会收到QoS 1消息-例如,订户可能会按1,2,3,3,4的顺序接收它们,但不能按1,2,3,2,3,4的顺序接收它们。将运行中窗口设置为1还意味着即使发布者针对同一主题发送具有不同QoS级别的消息序列,也将保留顺序。

4.7 Topic Names and Topic Filters(主题名称和主题过滤器)

4.7.1 Topic wildcards(主题通配符)

主题级别分隔符用于将结构引入主题名称。 如果存在,它将主题名称分为多个“主题级别”。

订阅的主题过滤器可以包含特殊的通配符,使您可以一次订阅多个主题。

可以在主题过滤器中使用通配符,但不得在主题名称[MQTT-4.7.1-1]中使用通配符。

4.7.1.1 Topic level separator(主题级别分隔符

正斜杠('/'U + 002F)用于分隔主题树中的每个级别,并为主题名称提供层次结构。 当订阅客户端指定的主题过滤器中遇到两个通配符中的任意一个时,主题级别分隔符的使用就很重要。 主题级别分隔符可以出现在“主题过滤器”或“主题名称”中的任何位置。 相邻主题级别分隔符表示长度为零的主题级别。

4.7.1.2 Multi-level wildcard(多层通配符)

数字符号('#'U + 0023)是通配符,与主题中任意数量的级别相匹配。 多层通配符表示父级和任意数量的子级。 多级通配符必须单独或在主题级分隔符之后指定。 无论哪种情况,它都必须是主题过滤器[MQTT-4.7.1-2]中指定的最后一个字符。

例如,如果客户订阅“ sport / tennis / player1 /#”,它将接收使用以下主题名称发布的消息:

· “sport/tennis/player1”

· “sport/tennis/player1/ranking”

· “sport/tennis/player1/score/wimbledon”

 

· “sport/#” also matches the singular “sport”, since # includes the parent level.

· “#” is valid and will receive every Application Message

· “sport/tennis/#” is valid

· “sport/tennis#” is not valid

· “sport/tennis/#/ranking” is not valid

4.7.1.3 Single level wildcard(单级通配符)

加号('+'U + 002B)是仅与一个主题级别匹配的通配符。

单级通配符可以在主题过滤器的任何级别(包括第一级和最后一级)中使用。 在使用的地方,它必须占据整个过滤器[MQTT-4.7.1-3]的级别。 它可以在“主题过滤器”中的多个级别上使用,并且可以与多级通配符一起使用。

非规范性说明

For example, “sport/tennis/+” matches “sport/tennis/player1” and “sport/tennis/player2”, but not “sport/tennis/player1/ranking”. Also, because the single-level wildcard matches only a single level, “sport/+” does not match “sport” but it does match “sport/”.

非规范性说明

·         “+” is valid
·         “+/tennis/#” is valid
·         “sport+” is not valid
·         “sport/+/player1” is valid                                                                                                                                           
·         “/finance” matches “+/+” and “/+”, but not “+”

4.7.2  Topics beginning with $(以$开头的主题)

服务器不能匹配主题过滤器开始使用通配符(#或+)与主题名称以$字符[MQTT-4.7.2-1]开始。 服务器应防止客户端使用此类主题名称与其他客户端交换消息。 服务器实现可以使用以前导$字符开头的主题名称,以用于其他目的。

非规范性说明

  • $SYS/ 已被广泛用作包含服务器特定信息或控制API的主题的前缀
  • 应用程序不能出于自己的目的使用带有前导$字符的主题

非规范性说明

  •        A subscription to “#” will not receive any messages published to a topic beginning with a $
  •        A subscription to “+/monitor/Clients” will not receive any messages published to “$SYS/monitor/Clients”
  •        A subscription to “$SYS/#” will receive messages published to topics beginning with “$SYS/”
  •        A subscription to “$SYS/monitor/+” will receive messages published to “$SYS/monitor/Clients”
  •        For a Client to receive messages from topics that begin with $SYS/ and from topics that don’t begin with a $, it has to subscribe to both “#” and “$SYS/#”

4.7.3 Topic semantic and usage(主题的语法和用法)

以下规则适用于主题名称和主题过滤器:

  • 所有主题名称和主题过滤器必须至少一个字符长[MQTT-4.7.3-1]
  • 主题名称和主题过滤器区分大小写
  • 主题名称和主题过滤器可以包含空格字符
  • 开头或结尾的“ /”会创建不同的主题名称或主题过滤器
  • 仅包含“ /”字符的主题名称或主题过滤器有效
  • 主题名称和主题过滤器不得包含null字符(Unicode U + 0000)[Unicode] [MQTT-4.7.3-2]
  • 主题名称和主题过滤器是UTF-8编码的字符串,它们不得编码为超过65535字节[MQTT-4.7.3-3]。 参见第1.5.3节

主题名称或主题过滤器中级别的数量外没有其他限制,除了由UTF-8编码的字符串的总长度。

当执行订阅匹配时,服务器绝不能对主题名称或主题过滤器进行任何规范化,或者对无法识别的字符进行任何修改或替换[MQTT-4.7.3-4]。 主题过滤器中的每个非通配级别都必须与“主题名称”字符中的相应级别匹配,以使字符成功匹配。

非规范性说明

UTF-8编码规则意味着可以通过比较编码的UTF-8字节或比较解码的Unicode字符来执行主题过滤器和主题名称的比较

非规范性说明

  •  “ACCOUNTS” and “Accounts” are two different topic names
  •  “Accounts payable” is a valid topic name
  •  “/finance” is different from “finance”

将应用程序消息发送到其主题过滤器与附加到应用程序消息的主题名称匹配的每个客户端订阅。 主题资源可以由管理员在服务器中预定义,也可以在服务器接收到第一个订阅或具有该主题名称的应用程序消息时由服务器动态创建。 服务器还可以使用安全组件来有选择地授权给定客户端对主题资源的操作。

4.8 Handling errors(错误处理)

除非另有说明,否则,如果服务器或客户端遇到协议违规,则它必须关闭其上收到导致协议违规的控制数据包的网络连接[MQTT-4.8.0-1]。

客户端或服务器实现可能会遇到瞬态错误(例如,内部缓冲区已满),这会阻止成功处理MQTT数据包。

如果客户端或服务器在处理入站控制包时遇到暂态错误,则必须关闭其接收该控制包[MQTT-4.8.0-2]的网络连接。 如果服务器检测到暂时性错误,则不应断开连接或对其与任何其他客户端的交互产生任何其他影响。

5 安全

5.1 简介

本章仅作为指导,不具有规范性。 但是,强烈建议提供TLS [RFC5246]的服务器实现应使用TCP端口8883(IANA服务名称:secure-mqtt)

解决方案提供商应考虑许多威胁。 例如:

  • 设备可能受到威胁
  • 客户端和服务器中的静态数据可能可以访问
  • 协议行为可能会有副作用(例如“定时攻击”)
  • 拒绝服务(DoS)攻击
  • 通讯可能被截取,更改,重新路由或披露
  • 欺骗控制包的注入

MQTT解决方案通常部署在不利的通信环境中。 在这种情况下,实现通常需要提供以下机制:

  •  用户和设备的身份验证
  •  授权访问服务器资源
  •  MQTT控制包及其中包含的应用程序数据的完整性
  •  MQTT控制包及其中包含的应用程序数据的保密性

作为一种传输协议,MQTT仅关注消息传输,并且实施者有责任提供适当的安全功能。 通常通过使用TLS [RFC5246]来实现。

除了技术安全问题外,还可能存在地域因素(例如,美国-欧盟SafeHarbor [USEUSAFEHARB]),行业特定的因素(例如PCI DSS [PCIDSS])和法规注意事项(例如Sarbanes-Oxley [SARBANES])。

5.2 MQTT解决方案:安全性和认证

一个实现可能希望符合特定的行业安全标准,例如NIST网络安全框架[NISTCSF],PCI-DSS [PCIDSS],FIPS-140-2 [FIPS1402]和NSA Suite B [NSAB]。

有关在NIST网络安全框架[NISTCSF]中使用MQTT的指南,请参见MQTT补充出版物《 MQTT》和《用于改善关键基础设施网络安全的NIST框架》 [MQTT NIST]。 使用行业认可,独立验证和认证的技术将有助于满足合规性要求。

5.3 轻量级加密和受约束的设备

先进的加密标准[AES]和数据加密标准[DES]被广泛采用。

ISO 29192 [ISO29192]为加密原语提出了建议,这些密码原语经过特殊调整可在受限的“低端”设备上执行。

5.4实施说明

在实现或使用MQTT时,要考虑许多安全问题。 以下部分不应视为“检查表”。

一个实现可能想要实现以下一些或全部功能:

5.4.1 服务器对客户端的身份验证

5.4.2 服务器对客户端的授权

5.4.3 客户端对服务器的身份验证

5.4.4 应用消息和控制包的完整性

5.4.5 应用消息和控制包的私有性

5.4.6 不可拒绝的消息传输

5.4.7 检测客户端和服务器的危害

5.4.8 检测异常行为

5.4.9 其他安全考虑

5.4.10 Use of SOCKS

客户端的实现应注意,某些环境将需要使用SOCKSv5 [RFC1928]代理进行出站网络连接。 一些MQTT实现可以通过使用SOCKS来使用备用安全隧道(例如SSH)。 在实现选择使用SOCKS的地方,它们应同时支持匿名和用户名密码身份验证SOCKS代理。 在后一种情况下,实现应意识到SOCKS身份验证可能以纯文本形式进行,因此应避免使用相同的凭据连接到MQTT Server。

5.4.11安全配置文件

实现者和解决方案设计者可能希望将安全性视为可以应用于MQTT协议的一组配置文件。 下面提供了分层安全性层次结构的示例。

5.4.11.1 Clear communication profile(清除通信配置文件)

5.4.11.2 Secured network communication profile

5.4.11.3 Secured transport profile

5.4.11.4 Industry specific security profiles

6   Using WebSocket as a network transport

如果MQTT通过WebSocket [RFC6455]连接进行传输,则适用以下条件:

  • ·MQTT控制包必须在WebSocket二进制数据帧中发送。 如果收到任何其他类型的数据帧,则接收者必须关闭网络连接[MQTT-6.0.0-1]。
  • ·一个WebSocket数据帧可以包含多个或部分MQTT控制包。 接收者不得假定MQTT控制数据包在WebSocket帧边界[MQTT-6.0.0-2]上对齐。
  • ·客户端必须在其提供的[MQTT-6.0.0-3]的WebSocket子协议列表中包含“ mqtt”。
  • ·服务器选择并返回的WebSocket子协议名称必须为“ mqtt” [MQTT-6.0.0-4]。
  • ·用于连接客户端和服务器的WebSocket URI对MQTT协议没有影响。

6.1 IANA注意事项

该规范要求IANA使用以下数据在“ WebSocket子协议名称”注册表下注册WebSocket MQTT子协议:

MQTT V3.1.1 协议 规范_第48张图片

7 一致性

MQTT规范定义了MQTT Client实现和MQTT Server实现的一致性。

MQTT实现可以同时作为MQTT客户端和MQTT服务器实现。 既接受入站连接又建立与其他服务器的出站连接的服务器必须同时作为MQTT客户端和MQTT服务器[MQTT-7.0.0-1]。

为了与任何其他一致的实现[MQTT-7.0.0-2]互操作,一致的实现必须不要求使用本规范之外定义的任何扩展。

7.1一致性指标

7.1.1 MQTT服务器

MQTT服务器只有满足以下所有条件,才符合此规范:

  1. 服务器发送的所有控制包的格式与第2章和第3章中描述的格式匹配。
  2. 它遵循第4.7节中描述的主题匹配规则。
  3. 它满足以下各章中确定的所有MUST级别要求,但仅适用于客户的要求除外:

-第1章-简介

-第2章-MQTT控制数据包格式

-第3章-MQTT控制数据包

-第4章-操作行为

-第6章-(如果MQTT通过WebSocket连接传输)

-第7章-一致性指标

一致性服务器必须支持使用一种或多种基础传输协议,这些协议提供从客户端到服务器以及从服务器到客户端的有序无损字节流[MQTT-7.1.1-1]。 但是,一致性并不取决于它是否支持任何特定的传输协议。 服务器可以支持第4.2节中列出的任何传输协议,或者满足[MQTT-7.1.1-1]要求的任何其他传输协议。

7.1.2 MQTT客户端

MQTT客户端只有满足以下所有条件,才符合此规范:

  1. 客户端发送的所有控制包的格式与第2章和第3章中描述的格式匹配。
  2. 它满足以下各章中确定的所有“必须”级别的要求,但仅适用于服务器的要求除外:

-第1章-简介

-第2章-MQTT控制数据包格式

-第3章-MQTT控制数据包

-第4章-操作行为

-第6章-(如果MQTT通过WebSocket连接传输)

-第7章-一致性指标

合格的客户端必须支持使用一种或多种基础传输协议,这些协议提供从客户端到服务器以及从服务器到客户端的有序无损字节流[MQTT-7.1.2-1]。 但是,一致性并不取决于它是否支持任何特定的传输协议。 客户端可以支持第4.2节中列出的任何传输协议,或者满足[MQTT-7.1.2-1]要求的任何其他传输协议。

8.  Wirshark 抓包截图

理解协议,最好的方法就是结合已知的工具,解析查看协议各类型帧的收发数据,并比对协议规范。这里简单的抓取了基本的协议帧。

这里以 百度云天工物接入 作为 服务端,以MQTT FX(http://mqttfx.jensd.de/index.php)模拟客户端,来抓取部分协议帧,百度云天工物接入平台,作为成熟的IOT HUB 接入平台,支持已经相当完善,实际使用也可以满足。

MQTT FX 使用比较简单,使用方法官方有说明,也可以在百度/阿里等IOT接入帮助文档中看到相关使用说明,在此不做赘述。

MQTT V3.1.1 协议 规范_第49张图片

MQTT FX 配置:

MQTT V3.1.1 协议 规范_第50张图片

 

MQTT V3.1.1 协议 规范_第51张图片

MQTT V3.1.1 协议 规范_第52张图片

连接成功后,说明设备到云端是通的,可以开始数据包的抓取了。

CONNECT:

MQTT V3.1.1 协议 规范_第53张图片

 CONNECT ACK:

MQTT V3.1.1 协议 规范_第54张图片

PING Request:

MQTT V3.1.1 协议 规范_第55张图片

PING Response:

MQTT V3.1.1 协议 规范_第56张图片

Subscribe Request:

MQTT V3.1.1 协议 规范_第57张图片

Subscribe Ack:

MQTT V3.1.1 协议 规范_第58张图片

Publish Message:

MQTT V3.1.1 协议 规范_第59张图片

 

MQTT V3.1.1 协议 规范_第60张图片

Unsubscribe Request:

MQTT V3.1.1 协议 规范_第61张图片

 Unsubscribe Ack:

MQTT V3.1.1 协议 规范_第62张图片

 Publish Message( QoS 1):

 Publish Ack :

MQTT V3.1.1 协议 规范_第63张图片

注:5.0 的协议暂时还没有看

V3.1.1 协议官方链接:http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/

V5.0   协议官方链接:http://docs.oasis-open.org/mqtt/mqtt/v5.0/

你可能感兴趣的:(通讯,TCP/IP,MQTT)