Skip to content

MQTT v5 带来了很多新的特性,我们会尽量以通俗易懂的方式展示这些特性,并探讨这些特性对开发者的影响。到目前为止,我们已经探讨过这些 MQTT v5 新特性,今天我们将继续讨论: 订阅标识符订阅选项

订阅标识符

客户端可以在订阅时指定一个订阅标识符,服务端将在订阅成功创建或修改时建立并存储该订阅与订阅标识符的映射关系。当有匹配该订阅的 PUBLISH 报文要转发给此客户端时,服务端会将与该订阅关联的订阅标识符随 PUBLISH 报文一并返回给客户端。

因此,客户端可以建立订阅标识符与消息处理程序的映射,以在收到 PUBLISH 报文时直接通过订阅标识符将消息定向至对应的消息处理程序,这会远远快于通过主题匹配来查找消息处理程序的速度。

image20200723152010505.png

由于 SUBSCRIBE 报文支持包含多个订阅,因此可能出现多个订阅关联到同一个订阅标识符的情况。即便是分开订阅,也可能出现这种情况,但这是被允许的,只是用户应当意识到这样使用可能引起的后果。根据客户端的实际订阅情况,最终客户端收到的 PUBLISH 报文中可能包含多个订阅标识符,这些标识符可能完全不同,也可能有些是相同的,以下是几种常见的情况:

  1. 客户端订阅主题 a 并指定订阅标识符为 1,订阅主题 b 并指定订阅标识符为 2。由于使用了不同的订阅标识符,主题为 ab 的消息能够被定向至不同的消息处理程序。
  2. 客户端订阅主题 a 并指定订阅标识符为 1,订阅主题 b 并指定订阅标识符为 1。由于使用了相同的订阅标识符,主题为 ab 的消息都将被定向至同一个消息处理程序。
  3. 客户端订阅主题 a/+ 并指定订阅标识符为 1,订阅主题 a/b 并指定订阅标识符为 1。主题为 a/b 的 PUBLISH 报文将会携带两个相同的订阅标识符,对应的消息处理程序将被触发两次。
  4. 客户端订阅主题 a/+ 并指定订阅标识符为 1,订阅主题 a/b 并指定订阅标识符为 2。主题为 a/b 的 PUBLISH 报文将会携带两个不同的订阅标识符,一个消息将触发两个不同的消息处理程序。

image20200723152040226.png

这种 PUBLISH 报文中携带多个订阅标识符的情况,在消息速率低的时候通常不成问题,但在消息速率高时可能会引发一些性能问题,因此我们建议您尽量确保这种情况的出现都是您有意为之。

订阅选项

在 MQTT v5 中,你可以使用更多的订阅选项来改变服务端的行为。

image20200723161859058.png

QoS

参见 MQTT 消息服务质量等级

No Local

在 MQTT v3.1.1 中,如果你订阅了自己发布消息的主题,那么你将收到自己发布的所有消息。

而在 MQTT v5 中,如果你在订阅时将此选项设置为 1,那么服务端将不会向你转发你自己发布的消息。

Retain As Publish

这一选项用来指定服务端向客户端转发消息时是否要保留其中的 RETAIN 标识,注意这一选项不会影响保留消息中的 RETAIN 标识。因此当 Retain As Publish 选项被设置为 0 时,客户端直接依靠消息中的 RETAIN 标识来区分这是一个正常的转发消息还是一个保留消息,而不是去判断消息是否是自己订阅后收到的第一个消息(转发消息甚至可能会先于保留消息被发送,视不同 Broker 的具体实现而定)。

Retain Handling

这一选项用来指定订阅建立时服务端是否向客户端发送保留消息:

  • Retain Handling 等于 0,只要客户端订阅成功,服务端就发送保留消息。
  • Retain Handling 等于 1,客户端订阅成功且该订阅此前不存在,服务端才发送保留消息。毕竟有些时候客户端重新发起订阅可能只是为了改变一下 QoS,并不意味着它想再次接收保留消息。
  • Retain Handling 等于 2,即便客户订阅成功,服务端也不会发送保留消息。