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

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

服务质量

MQTT 在 QoS 1 下用一个报文确认一次投递,在 QoS 2 下用四个报文的握手确认;本 crate 在处理器完成后发送确认。

每种服务质量下的一次投递:服务器与服务之间交换的报文,以及处理器在何处运行MQTT 服务器本服务QoS 0:至多一次QoS 1:至少一次QoS 2:恰好一次PUBLISH处理器运行PUBLISH处理器运行PUBACK ack 时PUBLISH处理器运行PUBREC ack 时PUBRELPUBCOMP 由 rumqttc 完成
以文字阅读本图
  1. QoS 0:至多一次: PUBLISH; 处理器运行
  2. QoS 1:至少一次: PUBLISH; 处理器运行; PUBACK ack 时
  3. QoS 2:恰好一次: PUBLISH; 处理器运行; PUBREC ack 时; PUBREL; PUBCOMP 由 rumqttc 完成
  4. MQTT 服务器: PUBLISH; PUBLISH; PUBLISH; PUBREL
  5. 本服务: 处理器运行; 处理器运行; PUBACK ack 时; 处理器运行; PUBREC ack 时; PUBCOMP 由 rumqttc 完成
  6. PUBLISH → 处理器运行
  7. PUBLISH → 处理器运行
  8. 处理器运行 → PUBACK ack 时
  9. PUBLISH → 处理器运行
  10. 处理器运行 → PUBREC ack 时
  11. PUBREC ack 时 → PUBREL
  12. PUBREL → PUBCOMP 由 rumqttc 完成

服务质量要选两次:发布者为自己的消息选择,订阅为它接受的内容选择。投递按两者中较低的一个进行,所以 QoS 0 的发布到达 QoS 1 的订阅时仍是 QoS 0。描述符的 Qos 设置订阅这一侧,发布策略设置消息这一侧。

在 QoS 0 下,服务器发出 PUBLISH 之后就不再管它。没有任何东西返回,所以 QoS 0 投递没有可确认的东西:ack 返回 AckError::Unsupported,运行时把它记入日志。

在 QoS 1 和 QoS 2 下,服务器一直保存消息,直到服务作出应答。本 crate 以手动确认的方式连接,所以 rumqttc 把每个 PUBLISH 交给订阅,自己什么也不发送。投递被确认时,也就是处理器返回之后,确认才会发出:QoS 1 下是 PUBACK,QoS 2 下是 PUBREC。完成 QoS 2 的 PUBREL 和 PUBCOMP 由 rumqttc 自己交换。

MQTT 没有否定确认。服务从未确认的 QoS 1 或 QoS 2 投递留在服务器上。只有当持久会话在新连接上恢复时,服务器才会再次发送它,并标记为重复。会话一页用图说明了这种恢复,结算一页说明处理器的每种结果发送什么。

客户端在连接时声明一个 Receive Maximum:它在不确认的情况下最多接收多少个 QoS 1 和 QoS 2 投递。未确认的投递达到这个数目后,服务器在该连接上不再发送 QoS 1 或 QoS 2 消息,直到其中一个被确认。本 crate 默认声明 1000,receive_maximum 可以修改它。这个窗口就是慢速订阅积压投递的上限。QoS 0 投递不参与其中。

服务发起的发布,在 rumqttc 把消息放进它的请求通道后就返回,而不是在服务器确认之后。这个通道容纳 64 个请求。每个 QoS 1 和 QoS 2 发布都会保存到服务器确认为止。重连后如果会话仍然存在,rumqttc 按协议的规定重发这些发布。重连时如果开始了新会话,连接任务把它们作为新的发布再次发送。服务器无法认出它已经收到过的消息,所以这样的消息可能到达两次,QoS 2 也不例外。

这些流程就是协议自己的流程,出自 MQTT 5.0 标准的 4.3 节和 4.9 节。