【问题标题】:How to know if a persistent MQTT session is still available?如何知道持久 MQTT 会话是否仍然可用?
【发布时间】:2014-07-08 09:27:02
【问题描述】:

这是关于 MQTT 协议和使用 MQTT 客户端的一般问题。特别是我使用 mosquitto 作为服务器,使用 ruby​​-mqtt 作为客户端。

MQTT 提供了持久会话的概念,这意味着在客户端断开连接时保留以前的订阅,并且 qos > 0 的消息将排队。这意味着对于我的客户端实现,我可以在连接到代理后跳过订阅,除非是第一次。

问题是:如何确定我的订阅仍然存在?我想可能会出现这样一种情况,即启动了一个新服务器,它没有关于我以前的会话以及我的订阅的信息。

【问题讨论】:

    标签: mqtt


    【解决方案1】:

    为了反驳我的共同回答者,MQTT v3.1.1 为代理提供了一种机制来告诉正在重新连接的客户端会话已恢复。这是 CONNACK 消息期间提供的“会话存在”标志。

    说他们支持 MQTT v3.1.1 的客户/经纪人应该支持这个标志。例如,Paho 1.0 客户端都应该这样做(Python 客户端肯定会这样做),而即将发布的 1.4 版本的 mosquitto 在其对 MQTT v3.1.1 的现有支持的基础上增加了对这个标志的支持。

    还值得注意的是,这个是一个有用的功能,因为 MQTT v3.1.1 要求在每个 SUBSCRIBE 上传输保留的消息,无论之前是否存在订阅。

    【讨论】:

    • 啊,谢谢,这就是我所希望的答案。并不是我现在迫切需要保存那几个字节,而是我想确保可以合理使用持久性功能。在 v3.1.1 之前,我想知道将保留消息发布到“私人”主题(例如“会话//”)是否是一种解决方案。重新连接时,我会立即收到保留的消息,因此不需要再次订阅。您认为这是一个合理的解决方法吗?
    • 并非如此,因为保留消息和持久客户端可能会被区别对待。例如,Mosquitto 可以配置为删除旧的持久客户端,但不能删除保留的消息。
    • @ralight ...我在 CONNACK 消息中丢失了这个标志。我对 MQTT 3.1.1 的 M2Mqtt 支持正在开发中;-)
    【解决方案2】:

    实现持久会话的代理应该将该信息存储到磁盘/数据库,以便在重新启动后仍然存在。企业代理(例如 IBM MQ)甚至可以跨多个代理实例联合此信息以提供故障转移。

    话虽如此,您实际上通过跳过再次请求订阅可以节省什么?

    【讨论】:

    • 好吧,我实际节省的是订阅消息的传输,这在定期重新连接客户端的情况下可能会有所帮助(例如通过 gsm 的低能耗跟踪设备)。但是谢谢你的答案!
    • @hardillb - 现在允许代理丢弃状态,因此无法保证。
    【解决方案3】:

    MQTT 协议规范中没有办法知道您的订阅是否存在。

    这取决于代理:它可以支持永久存储来保存永久订阅以避免在发生故障(关闭)的情况下丢失它们。

    在客户端,根据协议,您知道在连接消息中使用 clean session = FALSE 您不需要在下一次重新连接时订阅。它不取决于您,而是取决于经纪人。

    保罗。

    【讨论】:

      【解决方案4】:

      你不能确定,这就是为什么我建议每次在应用程序开始时订阅你感兴趣的主题,在与clean_session = False联系时也是如此。

      【讨论】:

      • 感谢您的回答。我已经想到了,但我又想知道这个功能是什么意思。
      • 如果您知道(通过某种 OOB 方法?)您的代理已经持久化了您的客户端(例如,您知道它是具有存储的现有代理等),您可以通过不订阅来节省一些八位字节。即便如此,我觉得在申请开始时订阅更安全。
      • 在很多使用 GSM/GPRS 连接的情况下,您支付传输的字节数,因此您必须避免无用的流量。我认为您必须选择正确的代理并信任它(如果它具有容错性并提供持久存储),这样您就可以避免在每次重新连接时发送订阅消息,即使 clean session = false。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-16
      • 2021-08-22
      • 1970-01-01
      相关资源
      最近更新 更多