断线期间积压的 MQTT 指令,怎样用消息过期限制补发

2026-10-24

MQTT 5.0 的 Message Expiry Interval 限制应用消息在代理中等待投递的寿命。它与会话保留多久是两回事:会话仍在,不代表其中每条消息都应继续补发。展厅的瞬时提示和有时限指令应明确有效期,代理开始向匹配订阅者转发时还要扣除已经等待的时间。

环境和证据范围

适用于代理为离线订阅者保存消息的链路。本文只模拟尚未开始向该订阅者投递的队列,不涵盖设备已经接收后又在本地排队的时间。MQTT3.1.1没有同名属性;应用自己的expires_at也不能冒充代理已经支持MQTT5过期机制。

核对顺序

  1. 把“开机状态设定”和“此刻弹出一次提示”分开,逐种消息说明过期后如何处理。示例10秒寿命只是为了计算,不是展厅统一建议值;机械执行仍需设备侧约束。

  2. 记录代理接收时刻、原始有效期和开始转发时刻。剩余值=原始有效期减等待秒数;已过期且尚未开始转发的订阅者副本应删除。未带过期属性表示协议层没有这个寿命上限。

  3. 回放等待2秒、9秒、10秒和缺过期属性四类输入,核对已过期记录不能进入业务执行队列。恢复订阅之后还要区分“没补发”和“补发后被应用拒绝”,两者证据位置不同。

可复算的输入与预期

合成消息原始寿命10秒,等待2秒输出剩余8秒,等待9秒输出1秒,等待10秒输出“删除”;没有expiry的样例输出“无协议过期”。这份计算不模拟精确调度抖动,更不证明某款代理已配置成功。

剩余寿命是代理转发给客户端时仍需传递的属性,不是客户端重新获得一份完整原始寿命。若每级中间件都把10秒重新起算,消息会被无意延寿。桥接后重新发布属于新的应用行为,必须明确是否保留原始采样时间与业务截止时间。

下载与现场记录

下载本题合成输入与预期JSON、离线只读核验脚本和现场空白记录CSV。放在同一目录,用 Python 3 运行 python verify.py,逐项计算或解析后与预期比较,失败会显示差异。

现场字段包括 topic、received_at、expiry_s、forward_started_at、remaining_s、drop_reason。合成样例保持原样,实测另存并填写型号、版本、证据路径,未采集处留空。本地核验不代表真实设备、代理、浏览器或长期稳定性已测。

失败分支与移交

如果消息已发到客户端,代理过期规则不能追回它。应用也可能把已经接收的旧指令留在自己的队列;这时仍需要自带时间语义和执行前检查。把Session Expiry设短会清掉会话状态,不能作为所有消息有效期的粗暴替代。

交付时注明协议版本、代理是否支持该属性、发布库如何设置、订阅端能否看到剩余有效期。真实断网补发实验应保留脱敏抓包与业务入口时间,并记录过期消息对应的用户提示或人工补做流程。

基础背景可看孪生数据怎么接进来:从 Modbus、BACnet、OPC UA 到 MQTT 与时序库。排队消息之外,会话是否保留需分别核对MQTT 重连后订阅还在不在,怎样核对 Clean Start 与会话过期。更多资料在设备协议库。

需要接入中控时,可对照SoftControl设备联动需求核实适配范围;独立校验方法是否纳入交付需逐项约定。

一级资料

核对日期:2026-10-24。规范定义与本文应用约定分开,示例门限及脚本不自动代表产品原生能力。

需要展厅软硬件方案或定制开发?

加微信,把这一页发到你手机上

扫码加站长企业微信,会自动把这一页的链接发给你。问软件授权、报价,或者现场遇到问题,也可以直接聊。

去留微信

留言讨论

评论发布后会被人工复核,违规内容将被删除。

    还没有人评论,来说说你的看法

    如果发表没有反应,可以前往联系我们告诉我们。

    这个页面有问题?

    提交时会附带当前页面地址和浏览器信息,帮助我们定位问题。不填联系方式即为匿名。