emqx的Qos为1的情况下,会出现客户端断开之后再重连,造成消息收不到

错误报告

环境

  • EMQX 版本:5.0.11
  • 操作系统版本:

重现此问题的步骤

emqx的Qos为1的情况下,会出现客户端断开之后再重连,造成消息收不到
1.客户端第一次连接mqtt之后,消息是可以发送和接收的;
2. 很快的断开再链接就会出现消息收不到情况
3. cleanSession=false,会出现问题(服务端是5分钟断开客户端的连接);
4、cleanSession设置为true就短时间重新连接就是好的

预期行为

实际行为


功能请求

描述你需要的功能

为什么你需要这个功能


其他

clean session = false true 时,再次上线后需要重新订阅。
clean session = true false时,再次上线会使用之前的 session ,保留了主题订阅关系,所以可以收到消息。

这个回答应该返了,我们是cleansession=false,我们是Qos设置为2有断开第2次之后消息发不出去是必现问题,Qos为1偶现,
问一个技术问题,就是客户端作为发送端断开的时候,他的RUBREL消息没有发出去,断开重新连接,发送新的消息packetId会变吗, packetId是不是还是老的,如果是老的packetId也发不出去吗

附官方解释:
QoS 2 规定,发送方只有在收到 PUBREC 报文之前可以重传 PUBLISH 报文。一旦收到 PUBREC 报文并发出 PUBREL 报文,发送方就进入了 Packet ID 释放流程,不可以再使用当前 Packet ID 重传 PUBLISH 报文。同时,在收到对端回复的 PUBCOMP 报文确认双方都完成 Packet ID 释放之前,也不可以使用当前 Packet ID 发送新的消息。

因此,对于接收方来说,能够以 PUBREL 报文为界限,凡是在 PUBREL 报文之前到达的 PUBLISH 报文,都必然是重复的消息;而凡是在 PUBREL 报文之后到达的 PUBLISH 报文,都必然是全新的消息。

一旦有了这个前提,我们就能够在协议层面完成 QoS 2 消息的去重。

另外packet ID生成规则是不是跟内容有关系,我们看到的是没有发送出去的东西,下次相同内容还是一样的pakcet ID
Messsage Identifier:4 这个4就是 packet ID吧

抱歉,之前关于 clean session 的回答有误,已更改。

回答你的另一个问题:PacketID 取决于客户端实现逻辑,是客户端和 Broker 之间标识已发送及已接收报文的手段。
当客户端发送了 PUBLISH(QoS=2, PacketID=x) 报文后,不论这个客户端有没有收到 Broker 发送的 PUBREC 报文。只要 EMQX 没有收到过这个客户端发送的,对应之前 PacketID=x 的 PUBREL 报文,就不认为这个发布流程完成。
此时如果再次使用 PacketID=x 发送 PUBLISH 报文,EMQX 会报错 “Packet ID in use”。
如果需要使用 PacketID=x 重发之前的报文,注意需要将重发标志位 (DUP) 设为 1