MQTT中的持久会话允许客户端在多个连接中维持其订阅和消息状态。当一个客户端和MQTT代理(broker)建立了持久会话,代理(broker)存储客户端的订阅信息和任何针对该客户端未发送的消息。这样,如果这个客户端断开连接,然后重新连接,就可以无缝的恢复通信。本文中,将探究主题的持久会话,清理会话的核心功能。我们将深入了解持久会话如何通过实现可靠的消息传递、提供QoS级别保证以及促进客户端的高效重新连接来增强QoS,即使在存在间歇性连接或客户端断开连接的情况下也是如此。
什么是持久会话
为了从MQTT代理(broker)接收消息,一个客户端建立一个连接,订阅期望的主题。在一个非持久会话中,如果代理(broker)和客户端之间的连接中断,客户端就丢失了它的订阅,重新连接之后需要重新订阅。这对资源有限的客户端来说增加了负担。为了解决这个问题,当客户端连接到代理(broker)时,可以请求一个持久会话。
持久会话在代理(broker)上存储所有客户端相关的信息,当连接下线时,确保订阅和消息被保留。会话被客户端建立连接时提供的客户端id标记。要了解客户端和代理(broker)连接的建立过程,参见:http://t.csdnimg.cn/tsr65
持久会话中存储了什么
在一个持久会话中,代理(broker)存储了以下内容(即使客户端下线了)。一旦客户端重新连接,这些信息马上可用:
- 会话存在(即使没有订阅): 代理(broker)保留会话存在的相关的信息,重新连接后允许客户端恢复它之前的状态。
- 所有客户端的订阅: 代理(broker)存储了客户端所有已订阅的主题列表。这就确保当客户端重连时不需要重新订阅,节省了资源和时间。
- 客户端尚未确认的所有Qos 1和QoS 2级别的消息流: 代理(broker)跟踪所有以QoS 1和QoS 2 等级发送到客户端尚未确认的消息。这些消息被存储在代理(broker)的消息队列中,重连之后会被重新发送,确保可靠的消息传输。
- 所有QoS 1和QoS 2等级的、客户端离线时错过的消息: 当客户端离线时,有QoS 1和QoS 2等级的消息被发布到订阅的主题,代理(broker)存储这些信息。一旦客户端重连,它就接收排队的消息,阻止任何重要信息的丢失。
- 从客户端接收的所有等待完全确认的QoS 2消息: 对于客户端发送的QoS 2消息,代理(broker)跟踪着它们的确认状态。如果这些消息中的任何一条未被确认,则代理(broker)将保留它们,直到确认完成。
什么是干净会话及如何用其开始和结束持久会话
当建立连接到代理(broker)时,客户端通过设置cleanSession标志,可以启用或停用持久会话。这是它工作的原理:当cleanSession标志设置为true时,客户端明确请求一个非持久会话。在这种场景下,如果客户端和代理(broker)断开连接,所有之前持久会话中的排队信息和消息都会被抛弃。重连后客户端开启一个干净的状态。
另一方面,当cleanSession标志设置为false时,代理为客户端创建一个持久会话。这就意味着代理(broker)保存所有相关的信息和消息,即使客户端下线。这个会话保持不变,直到客户端明确请求一个干净会话。如果cleanSession被设置为false且代理已经有一个会话供客户端使用,它会使用存在的会话,客户端重连后发送所有之前排队的消息。
更多关于客户端与代理(broker)建立连接的信息,参见之间的文章:http://t.csdnimg.cn/tsr65
客户端如何知道会话已被存储
在MQTT 3.1.1或更高版本中,代理为响应客户端的连接请求而发送的CONNACK消息包含会话存在标志。这个标志对客户端来说是指示器,表明代理(broker)上之前已建立的会话是否可用。通过检查会话存在标志,客户端能够确定是否建立新的会话或重连已存在的。为了更加深入的了解连接的建立过程,参见之间的文章:http://t.csdnimg.cn/tsr65
客户端持久会话:确保本地消息持久化和确认
除了代理(broker)存储持久会话,每个MQTT客户端也在维持会话连续性上扮演了一个角色。当客户端请求服务器保留会话数据时,它将承担责任,并且必须存储以下信息:
- 所有QoS 1和QoS 2等级的代理未确认的消息流: 客户端跟踪所有它发送到代理(broker)的QoS 1和QoS 2等级的消息。这些消息存储在本地,直到代理(broker)确认这些消息的接收或完成。通过维护这些未确认的消息,如果需要,客户端确保它可以重新发送任意的消息,到达期望的可靠性等级。
- 所有从代理(broker)接收的待完成确认的QoS 2等级的消息: 当代理(broker)发送QoS 2等级消息到客户端,消息被客户端接收和处理。但是,在客户端确认这些消息被成功处理之前,客户端将这些消息存储在本地。这就确保了客户端能够处理任意的中断或连接断开的同时,维持消息传输的可靠性和完整性。
- 通过存储这些消息相关的详细信息在客户端,MQTT客户端可以主动维护会话持久性,并确保即使在具有挑战性的网络条件下也能成功处理消息。
MQTT会话管理最佳实践:加强消息传输和资源效率
使用MQTT时,考虑会话管理最佳实践以优化的你实现是很重要的。以下是一些准则,可帮助你确定何时使用持久会话和干净会话。
MQTT持久会话最佳实践
- 确保消息的稳定性: 如果你的客户端需要接收指定主题的所有消息,即使在离线时,持久会话是一种实现方式。这可以确保代理(broker)将客户端的消息排队,并在客户端重新连接时及时传递它们。
- 资源优化: 如果你的客户端资源有限,利用持久会话是有益的。存储客户端的订阅信息到代理(broker)有利于连接中断时快速恢复,减轻了客户端的负担。
- 重新发布: 如果客户端需要重新连接后重新发布QoS 1和QoS 2的消息,则需要持久会话。代理(broker)会保留这些消息,直到客户端返回在线,以确保其可靠传递。
MQTT干净会话最佳实践
- 只发布的客户端: 如果客户端只需要发布消息,而不需要订阅主题,干净会话是合适的。在这种场景中,代理(broker)不需要存储会话信息,或尝试传输QoS 1和QoS 2的消息,简化了会话管理流程。
- 避免脱机消息检查: 如果你的客户端离线时不需要接收消息,干净会话就足够了。它消除了存储和传递客户端在离线期间未订阅消息的开销。
MQTT消息存储周期:代理存储消息多长时间
人们常问代理能够存储会话信息和消息多长时间。这个答案依赖多种因素:
- 内存限制: 通常,消息存储的主要结束是托管代理(broker)的操作系统的内存限制。监控和分配足够的资源来处理预期的消息量至关重要。
- 具体用例: 管理消息存储周期的合适解决方案是基于你的应用场景。要考虑的因素包括保存消息的重要性、消息过期策略以及法规或合规性要求等。
通过遵循这些最佳实践,考虑上面提到的因素,你可以有效的管理MQTT会话,优化消息持久化,确保你的基于MQTT的解决方案的稳定连接。
记住基于你需求的唯一性和应用程序的需要,应用这些准则。
结论
理解和高效利用持久会话,排队机制和合适的会话管理,我们可以充分利用MQTT的潜能,构建健壮、可扩展和稳定的IoT消息应用。接下来的文章中,我们深入探究保留消息的概念以及它在MQTT中的工作原理。