【问题标题】:Is MQTT reliable over unreliable connection, such as a wifi-to-uart bridge?MQTT 在不可靠的连接上是否可靠,例如 wifi 到 uart 的桥接?
【发布时间】:2022-12-20 01:16:42
【问题描述】:

我正在 IoT 设备上应用 MQTT。 WiFi 到 UART 桥用于在主控制器 MCU 和 MQTT 代理之间提供无线网络连接。为了简化 MCU 上的代码,TCP 连接在 WiFi 到 UART 桥上进行管理。但是,由于 WiFi 转 UART 桥接器不支持 MQTT,因此 MQTT 客户端运行在 MCU 上。

现在,MCU 和代理之间的连接通过 UART,这是不可靠的。随机错误和丢失的发生概率很低,但不是零。在这种情况下,MQTT 还可靠吗?如果我将 MQTT QoS 级别设置为 2,它是否仍能保证每条消息准确传递一次?内容还保证是正确的吗?

【问题讨论】:

    标签: mqtt


    【解决方案1】:

    The MQTT protocol specifies 以下是关于 QOS 级别 2 的内容:

    In the QoS 2 delivery protocol, the sender:
    
    MUST assign an unused Packet Identifier when it has a new Application Message to publish [MQTT-4.3.3-1].
    MUST send a PUBLISH packet containing this Packet Identifier with QoS 2 and DUP flag set to 0 [MQTT-4.3.3-2].
    MUST treat the PUBLISH packet as “unacknowledged” until it has received the corresponding PUBREC packet from the receiver [MQTT-4.3.3-3]. Refer to section 4.4 for a discussion of unacknowledged messages.
    MUST send a PUBREL packet when it receives a PUBREC packet from the receiver with a Reason Code value less than 0x80. This PUBREL packet MUST contain the same Packet Identifier as the original PUBLISH packet [MQTT-4.3.3-4].
    MUST treat the PUBREL packet as “unacknowledged” until it has received the corresponding PUBCOMP packet from the receiver [MQTT-4.3.3-5].
    MUST NOT re-send the PUBLISH once it has sent the corresponding PUBREL packet [MQTT-4.3.3-6].
    MUST NOT apply Message expiry if a PUBLISH packet has been sent [MQTT-4.3.3-7].
    

    和:

    In the QoS 2 delivery protocol, the receiver:
    
    MUST respond with a PUBREC containing the Packet Identifier from the incoming PUBLISH packet, having accepted ownership of the Application Message [MQTT-4.3.3-8].
    If it has sent a PUBREC with a Reason Code of 0x80 or greater, the receiver MUST treat any subsequent PUBLISH packet that contains that Packet Identifier as being a new Application Message [MQTT-4.3.3-9].
    Until it has received the corresponding PUBREL packet, the receiver MUST acknowledge any subsequent PUBLISH packet with the same Packet Identifier by sending a PUBREC. It MUST NOT cause duplicate messages to be delivered to any onward recipients in this case [MQTT-4.3.3-10].
    MUST respond to a PUBREL packet by sending a PUBCOMP packet containing the same Packet Identifier as the PUBREL [MQTT-4.3.3-11].
    After it has sent a PUBCOMP, the receiver MUST treat any subsequent PUBLISH packet that contains that Packet Identifier as being a new Application Message [MQTT-4.3.3-12].
    MUST continue the QoS 2 acknowledgement sequence even if it has applied message expiry [MQTT-4.3.3-13].
    

    When a Client reconnects with Clean Start set to 0 and a session is present, both the Client and Server MUST resend any unacknowledged PUBLISH packets (where QoS > 0) and PUBREL packets using their original Packet Identifiers. This is the only circumstance where a Client or Server is REQUIRED to resend messages. Clients and Servers MUST NOT resend messages at any other time [MQTT-4.4.0-1].
    

    我不知道您是在使用图书馆还是自己实施,或者您是问题的接收者还是发送者。

    但是,如果您是发件人,只要您还没有收到发布确认 (PUBREC) 并且您设法重新连接,您应该重新发布任何尚未确认的消息。 如果您是接收者,您应该继续接收消息,直到您回复发布已收到(也称为 PUBREC)。如果您已经收到消息,您应该重新发送收到的发布。

    我不确定当连接在交换中间断开时库如何处理 QoS 2。他们似乎很可能会尝试重新连接,但如果您使用的话,您可能应该检查一下库文档。这也可能因图书馆而异。

    retain feature for a publish 也可能值得研究。 这可以确保最新的消息保留在服务器/代理上,以防您由于连接问题暂时无法接收它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-15
      • 2014-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-08
      相关资源
      最近更新 更多