3.9 SUBACK – 订阅确认

服务端发送SUBACK报文给客户端,用于确认它已收到并且正在处理SUBSCRIBE报文。

SUBACK报文包含一个原因码列表,用于指定授予的最大QoS等级或SUBSCRIBE报文所请求的每个订阅发生的错误。

3.9.1 SUBACK 固定报头 SUBACK Fixed Header

图 3-24 – SUBACK报文固定报头 SUBACK Packet Fixed Header
Bit 7 6 5 4 3 2 1 0
byte 1 MQTT控制报文类型 (9) 保留位
1 0 0 1 0 0 0 0
byte 2 剩余长度

剩余长度字段
可变报头长度加上有效载荷长度,编码为变长字节整数。

3.9.2 SUBACK 可变报头 SUBACK Variable Header

SUBACK报文可变报头按顺序包含以下字段:所确认的SUBSCRIBE报文标识符,属性(Properties)。

图例 3.25 – SUBACK报文可变报头

3.9.2.1 SUBACK 属性 SUBACK Properties

3.9.2.1.1 属性长度 Property Length

SUBACK可变报头中的属性长度被编码为变长字节整数。

3.9.2.1.2 原因字符串 Reason String

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

服务端使用此值向客户端提供附加信息。如果加上原因字符串之后的SUBACK报文长度超出了客户端指定的最大报文长度,则服务端不能发送此原因字符串 [MQTT-3.9.2-1]。包含多个原因字符串将造成协议错误(Protocol Error)。

3.9.2.1.3 用户属性 User Property

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

图 3-23 - SUBACK报文可变报头 SUBACK packet Variable Header
Bit 7 6 5 4 3 2 1 0
byte 1 报文标识符 MSB
byte 2 报文标识符 LSB

3.9.3 SUBACK 载荷 SUBACK Payload

有效载荷包含一个原因码列表。每个原因码对应SUBSCRIBE报文中的一个被确认的主题过滤器。SUBACK报文中的原因码顺序必须与SUBSCRIBE报文中的主题过滤器顺序相匹配 [MQTT-3.9.3-1]。

表 3-8 - 订阅原因码 Subscribe Reason Codes

16进制 原因码名称 说明
0 0x00 授予QoS等级0 订阅被接受且最大QoS等级为0。可能低于所请求的QoS等级。
1 0x01 授予QoS等级1 订阅被接受且最大QoS等级为1。可能低于所请求的QoS等级。
2 0x02 授予QoS等级2 订阅被接受且最大QoS等级为2。可能低于所请求的QoS等级。
128 0x80 未指明错误 订阅未被接受,且服务端不愿意透露原因或没有适用的原因码。
131 0x83 实现特定错误 SUBSCRIBE有效但不被服务端所接受。
135 0x87 未授权 客户端未被授权做此订阅。
143 0x8F 主题过滤器无效 主题过滤器格式正确,但不被允许。
145 0x91 报文标识符已被占用 指定的报文标识符正在被使用中。
151 0x97 超出配额 已超出实现限制或管理限制。
158 0x9E 共享订阅不支持 服务端不支持此客户端进行共享订阅。
161 0xA1 订阅标识符不支持 服务端不支持订阅标识符;订阅标识符不被接受。
162 0xA2 通配符订阅不支持 服务端不支持通配符订阅;订阅未被接受。

服务端发送SUBACK报文时必须对收到的每一个主题过滤器设置一种原因码 [MQTT-3.9.3-2]。

非规范评注

对于SUBSCRIBE报文中的每个主题过滤器,总有一个对应的原因码。如果原因码不是针对某个特定的主题过滤器(比如0x91(报文标识符已占用)),则对每个主题过滤器都使用此原因码。

第三章目录 MQTT控制报文

项目主页