MQTT如何获取到订阅之前的消息?

GPT-3.5:

MQTT协议本身不支持获取订阅之前的消息。MQTT是一种轻量级的发布/订阅消息传输协议,它的设计目标是提供一种高效、可靠的消息传输机制,但并不保留消息的历史记录。

当一个客户端订阅一个主题(topic)时,它只会接收到之后发布到该主题的消息。如果客户端在订阅之前有消息发布到该主题,它将无法获取到这些消息。

如果你需要获取订阅之前的消息,你可以考虑使用其他消息传输协议或者结合其他技术来实现。例如,你可以使用消息队列系统(如RabbitMQ、Apache Kafka等)来保存消息的历史记录,并在订阅时获取历史消息。另外,一些MQTT代理服务器也提供了扩展功能,可以保存消息的历史记录并提供查询接口,你可以查阅相关文档以了解更多信息。

Claude Instant:

您提出了一个好问题。MQTT协议本身不支持获取订阅之前已经发布的消息。

但是,有一些方法可以实现获取订阅之前的消息:

1. 使用支持持久订阅的MQTT代理或broker。例如Mosquitto broker就支持持久订阅,可以在订阅时从broker获取之前的消息。
2. 结合消息队列使用。可以将MQTT消息同时发布到消息队列中,订阅时从消息队列获取历史消息。例如Kafka、RabbitMQ等。
3. 客户端本地缓存。客户端在订阅前可以缓存来自该主题的消息,订阅时返回缓存内容。
4. 自定义应用层协议。比如定义一个获取历史消息的命令,客户端订阅后发送这个命令获取需要的历史消息。
5. 从外部数据库中查询。比如将MQTT消息同时持久化到数据库,订阅时从数据库查询所需历史消息。
6. 一些商业MQTT代理也提供了类似功能,可以参考它们的文档。

所以总的来说,MQTT本身不支持,但可以通过上述方式在应用层或使用其他组件来实现获取订阅前历史消息的功能。选择哪种方式要视具体业务和架构来定。

下面『内容』摘自:MQTT 协议学习:Retained(保留消息) 与 LWT(最后遗嘱)

『让我们来看一下这个场景:

你有一个温度传感器,它每三个小时向一个 Topic 发布当前的温度。那么问题来了,有一个新的订阅者在它刚刚发布了当前温度之后订阅了这个主题,那么这个订阅端什么时候能才能收到温度消息?

对的,它必须等到三个小时以后,温度传感器再次发布消息的时候才能收到。在这之前,这个新的订阅者对传感器的温度数据一无所知。

怎么来解决这个问题呢?

这个时候就轮到 Retained 消息出场解决这个问题了。Retained 消息是指在 PUBLISH 数据包中 Retain 标识设为 1 的消息,Broker 收到这样的 PUBLISH 包以后,将保存这个消息,当有一个新的订阅者订阅相应主题的时候,Broker 会马上将这个消息发送给订阅者。

Retained 消息

Retain 消息有以下一些特点:

  • 一个 Topic 只能有 1 条 Retained 消息,发布新的 Retained 消息将覆盖老的 Retained 消息;
  • 如果订阅者使用通配符订阅主题,它会收到所有匹配的主题上的 Retained 消息;
  • 只有新的订阅者才会收到 Retained 消息,如果订阅者重复订阅一个主题,也会被当做新的订阅者,然后收到 Retained 消息;
  • Retained 消息发送到订阅者时,消息的 Retain 标识仍然是 1,订阅者可以判断这个消息是否是 Retained 消息,以做相应的处理。

注意:Retained 消息和持久性会话没有任何关系,Retained 消息是 Broker 为每一个 Topic 单独存储的,而持久性会话是 Broker 为每一个 Client 单独存储的。

如果你想删除一个 Retained 消息也很简单,只要向这个主题发布一个 Payload 长度为 0 的 Retained 消息就可以了。

那么开头我们提到的那个场景的解决方案就很简单了,温度传感器每 3 个小时发布当前的温度的 Retained 消息,那么无论新的订阅者什么时候进行订阅,它都能收到温度传感器上一次发布的数据。』

使用MQTTX测试:

与MQTT broker成功建立连接

发布主题为:[testtopic/1111] 的普通消息

订阅主题为:[testtopic/1111] 的普通消息


见上图,没有收到任何消息

发布主题为:[testtopic/2222] 的Retained消息

订阅主题为:[testtopic/2222] 的Retained消息


见上图,收到了Retained的保留信息

posted @ 2023-11-03 11:48  未来的羁绊  阅读(744)  评论(0编辑  收藏  举报