EMQX 中离线设备重新上线后,如何收到离线期间发布的 QoS 1 消息?

你好,我想咨询一个关于 EMQX QoS 1 消息和离线设备的问题。

环境:

  • EMQX 版本:5.8.4
  • MQTT 协议版本:MQTT 3.1.1 / MQTT 5.0
  • 使用场景:IoT 设备消息下发

场景如下:

  1. 设备 B 使用固定 clientId 连接到 EMQX。
  2. 设备 B 订阅一个 Topic,例如:/device/{clientId}/control
  3. 设备 B 下线。
  4. 在设备 B 离线期间,其他客户端向该 Topic 发布一条 QoS 1 消息。
  5. 设备 B 后续使用相同 clientId 重新上线。
    期望结果:
    设备 B 重新上线后,可以收到离线期间发布的这条 QoS 1 消息。

最终目标:
我希望确认在 EMQX 中,如何通过正确的客户端参数和 broker 配置,让设备在离线后重新上线时,能够收到离线期间发布到其订阅 Topic 的 QoS 1 消息。

这个场景可以实现,关键是把会话保留下来(不要 clean session),并保证离线队列不被打满。

  1. 连接参数
  • 固定 clientId(你现在这点是对的)。
  • MQTT 3.1.1:clean_session=false
  • MQTT 5.0:clean_start=false,并设置 Session-Expiry-Interval > 0(比如 7200 秒)。
  1. EMQX 侧配置(v5.8.4)
mqtt {
  session_expiry_interval = 2h
  max_mqueue_len = 1000
}
  • session_expiry_interval:给 MQTT 3.1.1 客户端提供会话保留时长(MQTT 5.0 以客户端的 Session Expiry 为准)。
  • max_mqueue_len:离线队列上限,满了会丢最老消息,QoS 1 也会受影响。
  1. 如果你要求“节点重启后也不能丢离线消息”
durable_sessions {
  enable = true
}

这个功能在 5.7+ 可用,开启后非零过期会话会落盘;改完需要重启节点生效。
可以按这个最小复现验证:

  1. B 端用固定 clientId + 非 clean session 订阅后下线。
  2. A 端向该 topic 发一条 QoS 1。
  3. B 端用同一 clientId 重连。
  4. 预期会收到离线期间那条消息。