原文:www.hivemq.com/blog/mqtt-e…
本篇文章在翻译过程中,对相关内容进行了一些删减,比如文字超链接
作者: HiveMQ Team
发布时间: March 2, 2015
更新于: 2023年6月27日
保留消息就是一个MQTT消息将retained标识设置为true,代理服务器会根据对应的QoS对主题存储最后一条保留消息。通过主题表达式订阅主题的客户端,在订阅完成后,可立即收到一条保留消息。代理服务器仅仅会保留每个主题下的一条消息。这篇文章是基础课程系列的第八部分,基础课程共分10部,涵盖MQTT协议的核心特性,概念,优势。本篇我们将讨论什么是保留消息,为什么要使用它,如何使用它,什么时候使用它.
如果你正在寻找持久化会话和纯净式会话,请参见第七部分内容,探究一下持久化会话的主题。现在让我们开始探究保留消息。
如何区分普通MQTT消息和保留消息?
保留消息是MQTT协议中的一个重要特性,它可以减少消息发布的不确定性。通过保留已发布主题上的最后一条消息,订阅者甚至在非活跃状态也可以了解当前的状态
在MQTT协议中,值得注意的是,消息发布者是不能保证订阅客户端可以收到消息的。发布者的责任在于确保消息传递到代理服务器。同样,订阅客户端不能判断发布客户端什么时候会发送一条新消息到它订阅的主题上。消息之间的间隔时间差异非常大,从几秒到几分钟,甚至几小时。因此订阅客户端在新消息被发布之前是无法知晓当前主题的状态,这就是保留消息发挥重要作用的地方。
保留消息提供了一种解决方案来应对上边提到的问题。当一个客户端发布一条带“保留”标志的消息,代理服务器就会保留此条消息。因此,任何订阅了相应消息的主题都将接收到最后一条保留消息,即使最近消息发布者没有在活跃状态。
本质上,保留消息会为订阅者提供主题最新的状态快照,确保在任何发布频率下都能接收到最新状态的信息
MQTT中的保留消息结构是什么样子的?
MQTT保留消息是将retained标志设置为true的标准MQTT消息,为了表示保留消息的重要,当客户端发布一条保留消息时,代理服务器会连带QoS的主题消息。当一个客户端通过主题表达式订阅了匹配的保留消息主题时,它会立即收到保留消息。
注意,代理服务器仅仅会保留一条保留消息。
即使订阅客户端使用了通配符主题表达式,它依然可以接收到与之不精准匹配主题的保留消息。
例如, 如果 客户端 A 发布一条保留消息到myhome/livingroom/temperature
,稍后客户端 B 订阅主题myhome/#
, 客户端 B 在订阅完成后,会立即接收到myhome/livingroom/temperature
主题的保留消息。在识别到retained标识值为true时,订阅客户端可以按照自己的要求处理它。
保留消息对新订阅的客户端来说还是比较重要的,因为它可以立即获取到订阅主题的最新状态,而无需等待发布客户端后续更新。本质上,保留消息表示的是特定主题最后一次有效消息,它不一定是最新一条消息,但必须是retained标志为true的最近一条消息。
需要强调的是,保留消息是独立于持久化会话的。一旦代理服务器存储了保留消息,仅有一种方法可以删除它,我们可以简短的讨论一下,
现在你了解了保留消息的结构,让我们继续学习如何管理它。
如何发布一条保留消息?
对开发者来讲,发送一条保留消息是非常简单的事情,把消息标志为retained状态就可以了,你需要做的所有事情就是设置发布消息的retained标志为true. 这个标志会向代理服务器传达此条消息需要保留,并且让所有订阅这条消息主题的客户端可以收到它。好消息是大多数MQTT库都已经提供了便捷友好的api来设置这个标志。通过利用这个特性,开发者可以确保关键信息持久存在,并保持对订阅者的可访问性,即使他们稍后加入网络或遇到临时连接问题。在基于MQTT的系统中,保留消息为共享重要数据和实现无缝通信提供了强大的机制。
如何删除保留消息?
只有一种方法可以删除主题的保留消息。要实现这一点,只需发布一个不带payload的保留消息到存储保留消息的主题。当代理服务器接收到这个特殊的保留消息时,它将其标识为一个删除请求,并立即删除与该主题关联的保留消息。因此,新订阅者将不再收到以前为该特定主题保留的消息。
值得注意的是,在许多情况下,显式删除保留的消息可能没有必要。这是因为对于同一主题,每个新保留的消息都会自动覆盖前一个消息。因此,如果在主题上发布新的保留消息,它将替换并取代任何现有的保留消息,从而有效地实现与删除前一条消息相同的结果。这种行为确保订阅者接收到最新和相关的信息,从而在大多数场景中不需要手动删除。
什么时候使用保留消息,为什么使用它?
保留消息在许多场景中都很有价值,特别是在你需要一个新连接的订阅者能接立即收到消息。
保留消息在传递组件或者设备实时状态方面,又特别大的优点。例如,我们将设备1命名为"device1",然后将它的状态发布到“myhome/devices/device1/status”主题. 通过使用保留的消息,此主题的新订阅者在订阅后立即接收设备的状态(如在线或离线)。
同样,这也适用于定期传输数据的客户端,如温度读数、 GPS 坐标和其他相关信息。如果没有保留消息,新订阅的客户端将仍然不知道消息间隔之间的数据更新。利用保留的消息,可以无缝地为连接客户端提供最新的和准确的值,确保他们可以立即访问关键信息。
结尾: MQTT生态环境中的保留消息概述
如您所见,保留消息在MQTT通信中发挥着关键作用,它解决了不确定消息传递的挑战,并提供了对主题最后已知状态的直接访问。通过启用对主题上的最新消息的保留,订阅者可以随时了解当前状态,即使在不活跃期间也是如此。
保留消息有利于提供状态更新,确保新订阅客户端接收相关信息,而不必等待随后的消息发布。利用保留的消息,MQTT增强了客户端和代理服务器之间高效可靠的通信,提高了IoT和消息传递应用程序的整体效率。