跳到主要内容
英文版本为准

本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。

主题

MQTT 服务器把消息投递给过滤器与其主题匹配的每个订阅,以及共享组中的一个成员,并保存保留消息。

向 devices/dev42/telemetry 的一次发布:服务器把它复制给每个匹配的订阅和共享组中的一个成员,带保留标志时还会保存它共享组 workers发布者向主题发送devices/dev42/telemetryMQTT 服务器把主题与每个订阅的过滤器逐一匹配devices/dev42/telemetry相同的主题devices/+/telemetry+ 匹配一级devices/## 匹配其余部分devices/+/state不匹配devices/+/telemetry成员 1 收到devices/+/telemetry成员 2 收不到保留消息该主题的最后一条之后才加入的订阅没有订阅匹配的消息被丢弃,除非它是保留消息
以文字阅读本图
  1. 共享组 workers: devices/+/telemetry 成员 1 收到; devices/+/telemetry 成员 2 收不到
  2. 发布者向主题发送 devices/dev42/telemetry → MQTT 服务器 把主题 与每个 订阅的 过滤器 逐一匹配: PUBLISH
  3. MQTT 服务器 把主题 与每个 订阅的 过滤器 逐一匹配 → devices/dev42/telemetry 相同的主题
  4. MQTT 服务器 把主题 与每个 订阅的 过滤器 逐一匹配 → devices/+/telemetry + 匹配一级
  5. MQTT 服务器 把主题 与每个 订阅的 过滤器 逐一匹配 → devices/# # 匹配其余部分
  6. MQTT 服务器 把主题 与每个 订阅的 过滤器 逐一匹配 → devices/+/telemetry 成员 1 收到
  7. MQTT 服务器 把主题 与每个 订阅的 过滤器 逐一匹配 → 保留消息 该主题的最后一条: 设置了保留标志
  8. 保留消息 该主题的最后一条 → 之后才加入的 订阅
  9. devices/+/state 不匹配
  10. 没有订阅匹配的消息被丢弃, 除非它是保留消息

主题是由 / 分隔的一串层级。订阅给出一个主题过滤器,其中可以包含通配符。+ 恰好代表一个层级。# 代表主题的其余部分,包括它的父层级,并且只能放在最后。发布总是给出完整的主题:发往带通配符主题的发布,本 crate 在发送任何内容之前就会拒绝。

以 $ 开头的主题,例如服务器自己的 $SYS/...,永远不会被以通配符开头的过滤器匹配。服务只有写出这类主题的第一级,才能读取它们。

服务器把消息发送给每个与之匹配的订阅。当一个连接持有两个都能匹配的过滤器时,MQTT 5 允许服务器为每个订阅发送一个报文,每个报文都带上该订阅的标识符。Mosquitto 就是这样做的,本 crate 凭这个标识符区分各个副本,多路分解一页用图说明了这一点。

共享组分担工作。过滤器 $share/workers/devices/+/telemetry 在组 workers 中订阅 devices/+/telemetry,服务器把每条消息交给组内的一个会话。组外的订阅仍然收到属于自己的一份。

带保留标志的发布会留在它的主题上。服务器为每个主题保存最后一条保留消息,并把它发送给过滤器与之匹配的每个新订阅,共享组除外。载荷为空的保留发布会清除该主题上的保留消息。

服务器保存的,就是每个主题的这条保留消息,以及持久会话中尚未确认的消息,后者见会话一页的图。到达时没有任何订阅匹配、又不是保留消息的消息,就此消失。

消息以 MQTT 5 属性的形式携带消息头。用户属性是一对 UTF-8 字符串,内容类型、响应主题和关联数据各自是独立的属性。本 crate 把消息头映射到这些属性上,见消息头。MQTT 字符串不得包含 U+0000,服务器也可能因其他控制字符而关闭连接,所以本 crate 拒绝带有这类字符的消息头或主题。

这一模型就是协议自己的模型,出自 MQTT 5.0 标准:主题名和主题过滤器见 4.7 节,共享订阅见 4.8.2 节,保留消息见 3.3.1.3 节。投递如何确认,见服务质量。