【问题标题】:How to force MQTT broker to NOT clean session from Android Paho client?如何强制 MQTT 代理不从 Android Paho 客户端清除会话?
【发布时间】:2020-05-14 19:18:00
【问题描述】:

我正在尝试使用 MQTT(Android 上的 Paho 库,Linux 服务器上的 mosquitto 消息代理)在回合制游戏中传递动作,取代我多年前编写的自定义服务器。它的简单性和 pub-sub 设计看起来很完美:每个设备订阅一个唯一的 id 作为“主题”并将其作为其“地址”进行通信。然后其他设备可以通过发布到该地址来访问它。

它在我的测试 Linux 客户端中完美运行(使用 Ubuntu 上的 mosquitto-dev 库连接)。当安卓应用程序运行时,它可以在安卓上完美运行。在 Linux 客户端案例中,如果在应用程序未运行或未连接时发送消息,则应用程序在连接和订阅后立即收到消息。然而,在 Android 上,这不会发生。只有在订阅 android 客户端时由另一个客户端发送(或重新发送)的消息才会被传递。

我是 MQTT 的新手,但“cleanSession”连接参数似乎很清楚控制这一点:除非您“清理”会话,否则您会在未订阅时获得发布到您的主题的所有内容。在 Linux 客户端,将“true”传递给 mosquitto_new(..., clean_session, ...) 确实会阻止我的 Linux 客户端获取预连接​​消息。但在 Android 端,当 MqttConnectOptions 实例传递给 .connect() 时,调用 .setCleanSession(boolean) 没有任何效果。

我正在使用 1.1.+ 的 paho。根据https://github.com/eclipse/paho.mqtt.android.git 的 repo 中的标签,v1.1.1 是最新的。

implementation "org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.+"
implementation "org.eclipse.paho:org.eclipse.paho.android.service:1.1.+"

我怀疑这只是 Android Paho 库中的一个错误(这似乎在四年内没有解决。)但我希望我错了!有没有办法实现我想要的?

或者,有没有更好的库?我所做的谷歌搜索表明,尽管 Paho 已经很老了,但它仍然是大多数 Android 开发人员用来说 MQTT 的语言。

谢谢!

【问题讨论】:

    标签: android mqtt mosquitto paho


    【解决方案1】:

    关于 cleanSession 标志。 客户端和服务器可以存储会话状态,以使可靠的消息传递在一系列网络连接中继续。该位用于控制 Session 状态的生命周期。

    如果 CleanSession 设置为 0,则服务器必须根据当前会话的状态(由客户端标识符标识)恢复与客户端的通信。如果没有与客户端标识符关联的会话,服务器必须创建一个新会话。 Client 和 Server 必须在 Client 和 Server 断开连接后存储 Session。在将 CleanSession 设置为 0 的会话断开连接后,服务器必须存储更多的 QoS 1 和 QoS 2 消息,这些消息与客户端在断开连接时所拥有的任何订阅相匹配,作为会话状态的一部分。它还可以存储满足相同标准的 QoS 0 消息。

    有关 cleanSession 的更多信息:https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/csprd02/mqtt-v3.1.1-csprd02.html

    如果我正确理解您的要求,那么您确实需要使用 clenSession=true。您也可以尝试使用 QoS=0 发布和订阅。一些代理不存储 QoS=0 消息,mosquitto 也是如此。 (根据https://mosquitto.org/man/mqtt-7.html

    【讨论】:

    • 您确认我怀疑设置 cleanSession=true 应该有效。我想知道是不是这样。如果是,是否存在阻止它以我尝试使用它的方式工作的错误。谢谢你的回答。
    • 是的,Android 客户端可能存在错误。确保您使用 QoS=0 有助于解决此问题并实现预期结果。
    【解决方案2】:

    我找到了一种解决方法,并在此过程中证实了我的怀疑,即 MqttAndroidClient 类因不遵守该设置而被破坏。我尝试使用 MqttAsyncClient,而不是使用 MqttConnectOptions。代码更改是微不足道的,尽管在 Android 客户端知道并使用后台服务的情况下存在相当大的变化。通过使用这个不同类的简单更改,我能够连接和订阅并立即接收在我未连接时发布的所有消息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-07
      • 2023-03-22
      • 2018-08-31
      • 2018-03-17
      • 2016-10-27
      相关资源
      最近更新 更多