在 MQTT 中,发布消息的客户端无法保证订阅的客户端确实收到了消息。发布客户端只能确保消息安全地传递给代理。基本上,订阅客户端也是如此。连接和订阅主题的客户端无法保证发布客户端何时会在其感兴趣的主题之一中发布消息。发布者可能需要几秒钟、几分钟或几小时才能在其中一个订阅主题中发送新消息。在发布下一条消息之前,订阅客户端完全不知道该主题的当前状态。这种情况是保留消息发挥作用的地方。
保留的消息
保留消息是保留标志设置为 true 的普通 MQTT 消息。代理存储最后保留的消息和该主题的相应 QoS。每个订阅与保留消息主题匹配的主题模式的客户端在订阅后立即收到保留消息。代理为每个主题仅存储一条保留消息。
如果订阅客户端在他们订阅的主题模式中包含通配符,即使保留消息的主题不完全匹配,它也会收到保留消息。这是一个示例:客户端 A 将保留的消息发布到 myhome/livingroom/temperature。一段时间后,客户端 B 订阅了 myhome/#。客户端 B 订阅myhome/#后直接收到**myhome/livingroom/temperature保留消息。客户端 B(订阅客户端)可以看到该消息是保留消息,因为代理发送保留标志设置为 true 的保留消息。客户端可以决定如何处理保留的消息。
保留消息可帮助新订阅的客户在订阅主题后立即获得状态更新。保留的消息消除了发布客户端发送下一个更新的等待。
换句话说,关于某个主题的保留消息是最后一个已知的好值。保留的消息不必是最后一个值,但它必须是保留标志设置为 true 的最后一个消息。
重要的是要理解保留的消息与持久会话无关。一旦保留消息由代理存储,只有一种方法可以删除它。继续阅读以了解如何。
发送保留消息
从开发人员的角度来看,发送保留消息非常简单直接。您只需将 MQTT 发布消息的 保留标志设置为 true。通常,您的客户端库提供了一种设置此标志的简单方法。
删除保留的消息
还有一种非常简单的方法可以删除主题的保留消息:在要删除先前保留消息的主题上发送带有零字节有效负载的保留消息。代理删除保留的消息,新订阅者不再获得该主题的保留消息。通常,甚至不需要删除,因为每个新保留的消息都会覆盖之前的消息。
为什么以及何时应该使用保留消息?
当您希望新连接的订阅者立即接收消息(无需等到发布客户端发送下一条消息)时,保留消息是有意义的。 这对于在各个主题上更新组件或设备的状态非常有帮助。例如,device1 的状态是关于myhome/devices/device1/status主题。使用保留消息时,主题的新订阅者在订阅后立即获得设备的状态(在线/离线)。对于以间隔、温度、GPS 坐标和其他数据发送数据的客户端也是如此。如果没有保留消息,新订阅者会在发布间隔之间保持黑暗。 使用保留消息有助于立即为连接的客户端提供最后的良好价值。