【问题标题】:Changes in QoS 1 and 2 in MQTT 5MQTT 5 中 QoS 1 和 2 的变化
【发布时间】:2021-08-19 03:53:01
【问题描述】:

根据此处的 HiveMQ 站点:https://www.hivemq.com/blog/mqtt5-essentials-part2-foundational-changes-in-the-protocol/ 版本 5 中 QoS1 和 2 之间的一个很大区别是,对于未到达目的地的消息,“对于健康的连接,无需重试”。我不确定以下几点:

  • 我查看了标准,没有发现任何提及,有人可以确认这是真的吗?
  • 这是否意味着如果在消息传输过程中连接中断或由于无法访问接收方而导致消息未被确认是唯一会重新传输的情况?
  • 网络拥塞但 PINGREQ/PINGRES 仍然有效怎么办?

谢谢!

【问题讨论】:

    标签: mqtt


    【解决方案1】:

    V5 spec 声明:

    当客户端重新连接并将 Clean Start 设置为 0 并且存在会话时,客户端和服务器都必须使用其原始数据包标识符重新发送任何未确认的 PUBLISH 数据包(其中 QoS > 0)和 PUBREL 数据包。这是唯一需要客户端或服务器重新发送消息的情况。客户端和服务器不得在任何其他时间重新发送消息 [MQTT-4.4.0-1]。

    “不得”是对 V3 规范的更改(允许重新发送但不要求重新发送)。我相信这回答了您的第二个问题(规范非常明确,除了重新连接后不得重新发送消息)。

    网络拥塞但 PINGREQ/PINGRES 仍然有效怎么办?

    当收到PINGREQ 时,将发送PINGRESP;如果网络拥塞阻止在允许的时间窗口内交付,则连接将被丢弃;否则它将保持不变。 TCP 提供了按顺序传送数据包的保证,因此消息最终应该通过(我意识到这并不总是 100% 有效)。

    我不能说明为什么在 v5 规范中进行了此更改,但文章 you are reading 指出:

    实际上,这是一个非常糟糕的主意,因为重载的 MQTT 客户端可能会更加重载。

    Mosquitto 在 version 1.5 中放弃了对重试的支持,原因如下:

    QoS>1 的传出消息在超时后不再重试。 当客户端重新连接时,将重试消息。这种行为变化 可以通过考虑何时可能发生超时来证明其合理性。

    • 如果连接不可靠且已断开,但没有一端 注意,这些消息将在重新连接时重试。发送 额外的 PUBLISH 或 PUBREL 不会改变任何东西。
    • 如果客户端过载/无法响应/连接速度较慢,则 发送额外的 PUBLISH 或 PUBREL 不会帮助客户抓住 向上。一旦积压已清除,客户端将响应。如果不是 能够赶上,发送额外的副本也无济于事。

    【讨论】:

    • 这完全回答了我的问题,谢谢!
    • 考虑一下……现在看来 QoS 1 和 2 之间没有太大区别,因为任何重新传输都必须意味着重新连接,还是我错了?除非多路径会导致延迟并且在断开连接后仍然可能接收到重复的消息,否则在这种情况下它仍然有意义....
    • 任何时候重新发送消息都有可能重复; QOS 2 使用四部分握手来避免这种情况。不在计时器上重新发送消息确实会减少但不会消除这种情况首先发生的机会。部分处理的消息是会话的一部分,因此在使用 cleanSession=false 重新连接后,它们将被重新发送。
    猜你喜欢
    • 1970-01-01
    • 2017-07-23
    • 2015-01-13
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    • 2015-10-03
    • 2022-07-12
    • 2016-02-02
    相关资源
    最近更新 更多