lanxiner
V2EX  ›  编程

MQTT 通信协议 QOS 的疑问

  •  
  •   lanxiner · Aug 3, 2021 · 2657 views
    This topic created in 1777 days ago, the information mentioned may be changed or developed.

    我在开发 android 客户端时使用 MQTT 协议:当 QOS 等于 2 时,断网的情况下尝试推送数据到服务器,此时推送的数据会超时, 按理说网络恢复后所有的推送数据会自动再次发送. 不会出现丢失的情况. 但是我遇到某些手机会出现断网下发送的数据, 再次联网后无法自动再次发送,数据永久性的丢失了. [使用的 MQTT 是是 paho] 为什么会出现这种情况, 不同的手机 qos 的效果不同?

    Supplement 1  ·  Aug 3, 2021
    我寻思 paho 也是 MQTT 中挺强的 java 实现库, 不至于很好的实现 MQTT 的 QOS 吧
    5 replies    2022-07-26 22:26:16 +08:00
    yitingbai
        1
    yitingbai  
       Aug 3, 2021
    MQTT 没有你想象的那么稳定, 最好还是在应用层在做一次判断
    melsp
        2
    melsp  
       Aug 3, 2021 via Android
    mqtt 好熟悉啊,还是大三做物联网实验学习过
    masterclock
        3
    masterclock  
       Aug 3, 2021
    MQTT 协议理论上可以 QoS 2,但各种库未必真的能实现,比如超过最大外发缓存就会放弃数据,有些库会在调用发送时直接失败,有些库没有任何提醒直接丢数据
    ntdll
        4
    ntdll  
       Aug 3, 2021
    也在 Android 中使用了 MQTT,可以尝试 C/C++版本的 paho,NDK 编译一下也不麻烦。我目前是这么用的 MQTTv5,问题不大。
    我是自己编译了 C 版本的,通过 JNI 暴露简单的接口到 Java 。
    vfs
        5
    vfs  
       Jul 26, 2022
    你对于 QoS 2 的理解是对的。 作为服务器肯定会保证 QoS 2 不会丢失(通常会将消息持久化到数据库或者文件系统中,以确保数据不会丢失)。 但是作为客户端,通常没有这样的机制,对于没有成功发送的数据一般只能报一个错误给上层应用程序,此时重发的任务就留给上层应用程序了。你需要自己在应用程序层面重新发送没有发送成功的消息。

    举个例子,如果你把一条 QoS 2 的消息成功发送到了服务器,另外一个监听同样 topic 的客户端接收到了消息,但是还没有回复相应的 ack 或者说 ack 没有成功的到达服务器,此时服务器是需要在将来一个合适的时刻重新将这条消息发送给这个监听者的。

    但是如果你的客户端在发送消息时断网,或者消息没有成功达到服务器(此时客户端还没有收到来自服务器的 ack ),那么这条失败的消息是需要发送消息的客户端自己保存,在将来某个时刻重新发给服务器的。这里你是不能依赖服务器的。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5489 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 09:04 · PVG 17:04 · LAX 02:04 · JFK 05:04
    ♥ Do have faith in what you're doing.