为了接受来至MQTT broker的消息,客户端必须连接到broker并且创建自己感兴趣的订阅。如果客户端和broker之间的非持久性会话断开,客户端订阅的主题将会丢之,必须重新连接且重新订阅主题。在资源有限的情况下,每次重新订阅将会带来负担。为避免这种问题,客户端可以在连接到borker时请求一个持续性会话,持续性会话会将客户端相关的信息都存储在broker,ClientID将作为连接会话的标志。
在持久性会话中,broker保存了以下信息,以便离线客户端在下一次连接时可以立即获取。
存在的会话(即使没有订阅)
客户端所有订阅的内容
QoS 1和QoS2客户端还未确认的信息
所有 QoS 1 & 2客户端离线时错过的信息。
所有QoS2的,客户端还未完全完成确认的信息
当客户端连接到borker时,可以请求持续性会话。客户端使用cleanSession标志告诉broker,请求的哪种会话。
标志设置为True是,客户端不需要持久性连接。不管何种原因,当它断开连接时,当前的会话信息和所有的消息将会丢失。
当cleanSession标志设置为false时,broker会为客户端创建一个持续性连接,所有的会话信息和消息将会被保留,直到下一次客户端将cleanSession标志设置为true。如果客户端将cleanSession标志设置为false且broker已经有了客户端的连接会话,客户端连接时broker会使用已有的会话并将之前排队的信息传递给client。
客户端和broker之间如何建立连接可参考第三节内容。
从MQTT3.1.1开始, broker发出的CONNACK(连接确认)消息中包含了一个会话持久标志,这个标志告诉客户端之前连接到broker的会话是否可用。
类似于broker,每个MQTT客户端也必须存储持久性会话。当一个客户端请求服务器保留会话数据时,客户端也会对应的保留一下信息:
所有QoS1 或2信息流中,还未被broker确认的消息。
所有QoS2信息流中还未被broker完全确认的消息。
下面的指引将帮助你决定何时使用持久性会话或清洁会话。
客户端必须从某个主题获取所有消息,即使它处于离线状态。您希望代理对客户端的消息进行排队,并在客户端重新联机后立即传递它们。
客户资源有限。您希望代理存储客户端的订阅信息并快速恢复中断的通信。
客户端需要在重新连接后恢复所有 QoS 1 和 2 发布消息。
客户端只需要向主题发布消息,客户端不需要订阅主题。您不希望代理存储会话信息或重试 QoS 1 和 2 消息的传输。
客户端不需要获取离线丢失的消息。
人们经常问经纪人将会话存储多长时间。简单的答案是:代理存储会话,直到客户端重新联机并接收到消息。但是,如果客户端长时间不在线会怎样? 通常,操作系统的内存限制是消息存储的主要约束。这种情况没有标准答案。正确的解决方案取决于您的用例。