3.14 DISCONNECT – 断开通知

DISCONNECT报文是客户端发给服务端的最后一个MQTT控制报文。表示客户端为什么断开网络连接的原因。客户端和服务端在关闭网络连接之前可以发送一个DISCONNECT报文。如果在客户端没有首先发送包含原因码为0x00(正常断开)DISCONNECT报文并且连接包含遗嘱消息的情况下,遗嘱消息会被发布。更多细节,参考3.1.2.5节。

服务端不能发送DISCONNECT报文,直到它发送了包含原因码小于0x80的CONNACK报文之后 [MQTT-3.14.0-1]。

3.14.1 DISCONNECT 固定报头 DISCONNECT Fixed Header

图例 3-35 – DISCONNECT 报文固定报头 DISCONNECT packet Fixed Header
Bit 7 6 5 4 3 2 1 0
byte 1 MQTT控制报文类型 (14) 保留位
1 1 1 0 0 0 0 0
byte 2 剩余长度

服务端或客户端必须验证所有的保留位都被设置为0,如果他们不为0,发送包含原因码为0x81(无效报文)的DISCONNECT报文,如4.13节所述 [MQTT-3.14.1-1]。

剩余长度字段
等于可变报头的长度,编码为变长字节整数。

3.14.2 DISCONNECT 可变报头 DISCONNECT Variable Header

DISCONNECT报文的可变报头按顺序包含以下字段:断开原因码,属性(Properties)。属性的编码规则如2.2.2节所述。

3.14.2.1 DISCONNECT 断开原因码 Disconnect Reason Code

可变报头的第1个字节是断开原因码。如果剩余长度小于1,则表示使用原因码0x00(正常断开)。

单字节无符号断开原因码字段如下所示。

表 3-10 – 断开原因值 Disconnect Reason Code

16进制 原因码名称 发送端 说明
0 0x00 正常断开 客户端或服务端 正常关闭连接。不发送遗嘱。
4 0x04 包含遗嘱消息的断开 客户端 客户端希望断开但也需要服务端发布它的遗嘱消息。
128 0x80 未指定错误 客户端或服务端 连接被关闭,但发送端不愿意透露原因,或者没有其他适用的原因码。
129 0x81 无效的报文 客户端或服务端 收到的报文不符合本规范。
130 0x82 协议错误 客户端或服务端 收到意外的或无序的报文。
131 0x83 实现指定错误 客户端或服务端 收到的报文有效,但根据实现无法进行处理。
135 0x87 未授权 服务端 请求没有被授权
137 0x89 服务端正忙 服务端 服务端正忙且不能继续处理此客户端的请求。
139 0x8B 服务正关闭 服务端 服务正在关闭。
141 0x8D 保持连接超时 服务端 连接因为在超过1.5倍的保持连接时间内没有收到任何报文而关闭。
142 0x8E 会话被接管 服务端 另一个使用了相同的客户标识符的连接已建立,导致此连接关闭。
143 0x8F 主题过滤器无效 服务端 主题过滤器格式正确,但不被服务端所接受。
144 0x90 主题名无效 客户端或服务端 主题名格式正确,但不被客户端或服务端所接受。
147 0x93 超出接收最大值 客户端或服务端 客户端或服务端收到了数量超过接收最大值的未发送PUBACK或PUBCOMP的发布消息。
148 0x94 主题别名无效 客户端或服务端 客户端或服务端收到的PUBLISH报文包含的主题别名大于其在CONNECT或CONNACK中发送的主题别名最大值。
149 0x95 报文过大 客户端或服务端 报文长度大于此客户端或服务端的最大报文长度。
150 0x96 消息速率过高 客户端或服务端 收到的数据速率太高。
151 0x97 超出配额 客户端或服务端 已超出实现限制或管理限制。
152 0x98 管理操作 客户端或服务端 连接因为管理操作被关闭。
153 0x99 载荷格式无效 客户端或服务端 载荷格式与指定的载荷格式指示符不匹配。
154 0x9A 不支持保留 服务端 服务端不支持保留消息。
155 0x9B 不支持的QoS等级 服务端 客户端指定的QoS等级大于CONNACK报文中指定的最大QoS等级。
156 0x9C (临时)使用其他服务端 服务端 客户端应该临时使用其他服务端。
157 0x9D 服务端已(永久)移动 服务端 服务端已移动且客户端应该永久使用其他服务端。
158 0x9E 不支持共享订阅 服务端 服务端不支持共享订阅。
159 0x9F 超出连接速率限制 服务端 此连接因为连接速率过高而被关闭。
160 0xA0 最大连接时间 服务端 超出为此连接授予的最大连接时间。
161 0xA1 不支持订阅标识符 服务端 服务端不支持订阅标识符;订阅未被接受。
162 0xA2 不支持通配符订阅 服务端 服务端不支持通配符订阅;订阅未被接受。

客户端或服务端发送DISCONNECT报文时必须使用一种DISCONNECT原因码 [MQTT-3.14.2-1]。如果原因码为0x00(正常断开)且没有属性,原因码和属性长度可以被省略。这种情况下DISCONNECT报文剩余长度为0。

非规范评注

DISCONNECT报文用于指示断开的原因,例如没有确认报文(比如QoS等级0的发布消息)或当客户端或服务端不能继续处理连接。

非规范评注

客户端可以使用这些信息来决定是否重新连接,以及在重新尝试之前应该等待多长时间。

3.14.2.2 DISCONNECT 属性 DISCONNECT Properties

3.14.2.2.1 属性长度 Property Length

DISCONNECT报文可变报头中的属性(Properties)的长度被编码为变长字节整数。如果剩余长度小于2,属性长度使用0。

3.14.2.2.2 会话过期间隔 Session Expiry Interval

17 (0x11) ,会话过期间隔(Session Expiry Interval)标识符。
跟随其后的是用四字节整数表示的以秒为单位的会话过期间隔(Session Expiry Interval)。包含多个会话过期间隔将造成协议错误(Protocol Error)。

如果没有设置会话过期间隔,则使用CONNECT报文中的会话过期间隔。

会话过期间隔不能由服务端的DISCONNECT报文发送 [MQTT-3.14.2-2]。

如果CONNECT报文中的会话过期间隔为0,则客户端在DISCONNECT报文中设置非0会话过期间隔将造成协议错误(Protocol Error)。如果服务端收到这种非0会话过期间隔,则不会将其视为有效的DISCONNECT报文。服务端使用包含原因码为0x82(协议错误)的DISCONNECT报文,如4.13节所述。

3.14.2.2.3 原因字符串 Reason String

31 (0x1F) ,原因字符串(Reason String)标识符。
跟随其后的是UTF-8编码字符串表示断开原因。此原因字符串是为诊断而设计的可读字符串,不应该被接收端所解析。

如果此属性使得DISCONNECT报文的长度超出了接收端指定的最大报文长度,则发送端不能发送此属性 [MQTT-3.14.2-3]。包含多个原因字符串将造成协议错误(Protocol Error)。

3.14.2.2.4 用户属性 User Property

38 (0x26) ,用户属性(User Property)标识符。
跟随其后的是UTF-8字符串对。此属性可用于向客户端提供包括诊断信息在内的附加信息。如果加上用户属性之后的DISCONNECT报文长度超出了接收端指定的最大报文长度,则发送端不能发送此属性 [MQTT-3.14.2-4]。用户属性允许出现多次,以表示多个名字/值对,且相同的名字可以多次出现。

3.14.2.2.5 服务端参考 Server Reference

28 (0x1C) ,服务端参考(Server Reference)标识符。
跟随其后的是一个UTF-8编码字符串,客户端可以使用它来识别其他要使用的服务端。包含多个服务端参考将造成协议错误(Protocol Error)。

服务端发送包含一个服务端参考和原因码0x9C((临时)使用其他服务端)或0x9D(服务端已(永久)移动)的DISCONNECT报文,如4.13节所述。

关于如何使用服务端参考,参考4.11节服务端重定向。

图 3-24 - DISCONNECT 报文可变报头非规范示例 DISCONNECT packet Variable Header non-normative example

说明 7 6 5 4 3 2 1 0
断开原因码
byte 1 0 0 0 0 0 0 0 0
属性
byte 2 长度 (5) 0 0 0 0 0 1 1 1
byte 3 会话过期间隔标识符 (17) 0 0 0 1 0 0 0 1
byte 4 会话过期间隔标识符 (17) 0 0 0 0 0 0 0 0
byte 5 0 0 0 0 0 0 0 0
byte 6 0 0 0 0 0 0 0 0
byte 7 0 0 0 0 0 0 0 0

3.14.3 DISCONNECT 有效载荷 DISCONNECT Payload

DISCONNECT报文没有有效载荷。

3.14.4 DISCONNECT 行为 DISCONNECT Actions

发送端发送完DISCONNECT报文之后:

  • 不能再在此网络连接上发送任何MQTT控制报文 [MQTT-3.14.4-1]。
  • 必须关闭网络连接 [MQTT-3.14.4-2]。

接收到包含原因码为0x00(成功)的DISCONNECT时,服务端:

  • 必须丢弃任何与当前连接相关的遗嘱消息,而不发布它 [MQTT-3.14.4-3],如3.1.2.5节所述。

接收到DISCONNECT报文时,接收端:

  • 应该关闭网络连接

第三章目录 MQTT控制报文

项目主页