MQTT 持久会话 vs. Clean Session内幕一网打尽
1 前言
- 不稳定的网络
- 有限的硬件资源
物联网应用两大难题,MQTT 客户端与服务器的连接可能随时因网络波动及资源限制而异常断开。为解决网络连接断开对通信造成的影响,MQTT 协议提供持久会话功能。
MQTT 客户端在发起到服务器的连接时,可设置是否创建一个持久会话。持久会话会保存一些重要数据,以使会话能在多个网络连接中继续。
2 作用
- 避免因网络中断导致需要反复订阅带来的额外开销
- 避免错过离线期间的消息
- 确保 QoS 1 和 QoS 2 的消息质量保证不被网络中断影响
3 持久会话需存储哪些数据?
通过上文我们知道持久会话需要存储一些重要的数据,以使会话能被恢复。这些数据有的存储在客户端,有的则存储在服务端。
客户端中存储的会话数据:
- 已发送给服务端,但是还没有完成确认的 QoS 1 与 QoS 2 消息
- 从服务端收到的,但是还没有完成确认的 QoS 2 消息
服务端中存储的会话数据:
- 会话是否存在,即使会话状态其余部分为空。
- 已发送给客户端,但是还没有完成确认的 QoS 1 与 QoS 2 消息。
- 等待传输给客户端的 QoS 0 消息(可选),QoS 1 与 QoS 2 消息。
- 从客户端收到的,但是还没有完成确认的 QoS 2 消息,遗嘱消息和遗嘱延时间隔。
4 MQTT Clean Session
控制会话状态生命周期的标志位:
true
表示创建一个新的会话,在客户端断开连接时,会话将自动销毁false
表示创建一个持久会话,在客户端断开连接后会话仍然保持,直到会话超时注销
持久会话能被恢复的前提是客户端使用固定 Client ID 再连,如 Client ID 动态,连接成功后将会创建一个新的持久会话。
如下Dashboard,图中连接虽然是断开状态,但因是持久会话,仍能被查看到,且可在 Dashboard 中手动清除该会话:
EMQX 也支持在 Dashboard 设置 Session 相关参数。
MQTT 3.1.1 没规定持久会话何时过期,仅从协议层理解,这持久会话应永久存在。但实际场景不现实,因为它非常占服务端资源,所以服务端实际向用户提供一个全局配置来限制会话过期时间。如设置会话过期时间 5 min,最大消息数为 1000 条,且不保存 QoS 0 消息。
5 使用
打开 MQTTX 后如下所示,点击 New Connection
按钮创建一个 [MQTT 连接]。
创建名为 MQTT_V3
的连接,Clean Session 为关闭状态(即为 false),MQTT 版本选择 3.1.1,然后点击右上角的 Connect
按钮。
连接成功后订阅 clean_session_false
主题,且 QoS 设置为 1。
订阅成功后,点击右上角的断开连接按钮。然后,创建一个名为 MQTT_V3_Publish
的连接,MQTT 版本同样设置为 3.1.1,连接成功后向 clean_session_false
主题发布两条 QoS 1 消息。
然后选中 MQTT_V3 连接,点击连接按钮连接至服务器,将会成功接收到两条离线期间的消息。
6 MQTT 5.0 中的会话改进
MQTT 5.0 中将 Clean Session 拆成:
-
Clean Start
指定连接时是创建一个全新的会话还是尝试复用一个已存在的会话
-
Session Expiry Interval
指定网络连接断开后会话的过期时间
Clean Start 为 true
时表示必须丢弃任何已存在的会话,并创建一个全新的会话;为 false
时表示必须使用与 Client ID 关联的会话来恢复与客户端的通信(除非会话不存在)。
Session Expiry Interval 解决了 MQTT 3.1.1 中持久会话永久存在造成的服务器资源浪费问题。设置为 0 或未设置,表示断开连接时会话即到期;设置为大于 0 的数值,则表示会话在网络连接关闭后会保持多少秒;设置为 0xFFFFFFFF
表示会话永远不会过期。
7 FAQ
当会话结束后,保留消息还存在么?
[MQTT 保留消息]不是会话状态的一部分,它们不会在会话结束时被删除。
客户端如何知道当前会话是被恢复的会话?
MQTT 协议从 v3.1.1 开始,就为 CONNACK 报文设计了 Session Present 字段。当服务器返回的该字段值为 1 时,表示当前连接将会复用服务器保存的会话。客户端可通过该字段值决定在连接成功后是否需要重新订阅。
使用持久会话的建议
- 不能使用动态 Client ID,需要保证客户端每次连接的 Client ID 都是固定的。
- 根据服务器性能、网络状况、客户端类型等合理评估会话过期时间。设置过长会占用更多的服务端资源,设置过短会导致未重连成功会话就失效。
- 当客户端确定不再需要会话时,可使用 Clean Session 为 true 进行重连,重连成功后再断开连接。如果是 MQTT 5.0 则可在断开连接时直接设置 Session Expiry Interval 为 0,表示连接断开后会话即失效。
8 总结
至此完成对 MQTT 持久会话的介绍,并通过桌面客户端演示了 Clean Session 的使用。读者可参考本文借助 MQTT 持久会话实现离线消息的接收及降低订阅开销。
作者简介:魔都国企技术专家,多家大厂后台研发和架构经验,负责复杂度极高业务系统的模块化、服务化、平台化研发工作。具有丰富带团队经验,深厚人才识别和培养的积累。
参考:
本文由博客一文多发平台 OpenWrite 发布!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
不是 GPT4 用不起,而是本地运行 Mixtral-8x7B 更有性价比
当 GPT4 刚问世时,社区猜测它用了“多少亿个参数”才实现的如此惊人的性能。 但事实证明,GPT4 的创新不仅仅是“更多参数”。 它本质上是 8 个 GPT 3.5 模型一起工作。 这些模型中的每一个都针对不同的任务(即“专家”)进行了调整。 这称为“专家组合”(Mixture of Experts,缩写为 MoE)。 输入文本根据内容和所需任务会被分派给 8 个专家模型中的一个。 然后,小组中的其他专家模型会评估结果,从而改进未来的问题的分配。 Mistral AI 的 Mixtral 8x7B 是基于 8 个 Mistral-7B 模型的开源 MoE LLM。 借助 WasmEdge,你可以在任意设备上创建并运行该 LLM 的跨平台应用程序,包括自己的笔记本电脑、边缘设备和服务器。 在自己的设备上运行 Mixtral-8x7B 步骤1:通过以下命令行安装 WasmEdge。 curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | bash -s -- --plu...
- 下一篇
青语言新版本 V1_20240102 发布
大家好! 新的一年新的开始,2024年伊始,我们发布了新一版的青语言,期待2024与大家一起共同进步。 V1.0之后,青语言的版本号将采用V1_yyyyMMdd格式,本次发布的版本为V1_20240102。 青语言下载 本次主要更新内容: 1、修复了 @解析Json函数。之前版本中使用了一个十分简陋的实现,存在Bug,新版本中已修复。 2、程序同目录下如果存在主程序.q文件,会在解释器或编辑器启动时直接运行,作为目前无法打包程序的一个临时替代方案。 3、释放@运行原生脚本函数。青语言核心在.Net的基础上实现,没有依赖任何第三方库。但是细心的朋友可能会发现,从第一个版本开始,青语言项目就引用了CSharpScript包(已改为CS-Script),这是我们为了在青语言中嵌入C#脚本而提前做的规划。之前的版本中这个功能未能很好的实现,故而没有释出,在本次的新版本中,我们提供了这项功能。 以下是在青语言中嵌入C#脚本的示例 #结果 = 0 @运行原生脚本【10,#结果,"_Result.Val = _Params.Int() * 2;"】 通过 _Params和 _Result来和...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS8编译安装MySQL8.0.19
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Red5直播服务器,属于Java语言的直播服务器
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7