MQTT离线消息接收测试实现
目的及技术要点
目的 :
测试MQTT客户端断线,重新上线后,补全离线后所订阅的离线消息。
技术要点:
Mqtt5支持离线消息接收的几个核心设置:
ClientId
CleanStart: false
SessionExpiry
Qos:2
CONNACK中的session present flag
ClientId用于唯一标识用户session。
CleanStart设置为0,表示创建一个持久会话,在客户端断开连接时,会话仍然保持并保存离线消息,直到会话超时注销。CleanStart设置为1,表示创建一个新的临时会话,在客户端断开时,会话自动销毁。
SessionExpiry即指定在CleanStart为0时,会话的保存时长,如果客户端未在用户定义的时间段内连接,则可以丢弃状态(例如,订阅和缓冲的消息)而无需进行清理。
Qos即消息的Quality of Service,若要支持离线消息,需要订阅端、发布端Qos >= 1
session present即在connect到mqtt服务器的返回结果ConnAck中,包含session present标识,该标识表示当前clientId是否存在之前的持久会话(persistent session),若之前已存在session(此时千万不要再次重复订阅topic,若再次订阅则之前的消息都将收不到),则session会保留之前的订阅关系、客户端离线时的消息(Qos>=1)、未ack的消息。重点说明一下session present的使用,在客户端连接到mqtt服务器并获取到connack中的isSessionPresent标识时,若isSessionPresent=true则已存在会话,此时无需再重复订阅topic(订阅关系已保存到session中,若再重复订阅则收不到之前的离线消息),可通过全局接收来处理离线消息和之后的新消息;若isSessionPresent=false则不存在session(又或者session已超期),此时需要重新订阅topic,且之前离线的消息都已接收不到,只能通过其他方式获取离线消息(例如IM后端服务的全量同步服务)。
如ClientId=1, CleanStart=false, SessionExpiry=3600s, Qos=2即指定clientId=1的会话为持久会话,用户在离线后3600s的的离线消息都会被Mqtt服务器保存,用户在离线时间不超过3600s且再次以ClientId=1重新上线时,是可以收到离线期间消息的补充推送的,同时Qos=2(exactly once)保证消息只会被客户端收到一次且一定一次。
————————————————
版权声明:本文为CSDN博主「罗小爬EX」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/luo15242208310/article/details/103971457
测试环境搭建及测试过程
使用EMQX4.2.1的默认配置搭建MQTT服务端,一台VM虚拟机,安装MQTT.fx-1.7.1作为MQTT客户端 ,用于客户端连接测试。
客户端2用于离线消息发送,运行在本机,设置:Clean Session = 0;Auto Reconnect = 1;
连接到服务器后,发送Topic是“test”,Qos = 1;发送消息是“Send01-09”
客户端1用于离线消息接收,运行在虚拟机中,设置:Clean Session = 0;Auto Reconnect = 1;Qos=1;
EMQX服务器端确认两个客户端已经连接,客户端1订阅消息成功。
断开客户端1所在的虚拟机的网络,模拟设备掉线。
在服务器端确认客户端1已经离线。
在客户端2发送消息是“Send01-09”,在服务器端可以看到“消息流入”是9条。
启用虚拟机的网卡,让客户端1自动恢复连接,等待约120秒后,客户端重新连接成功,自动接收离线消息合计9条,无数据丢失。
服务器端可以看到“消息流出”也是9条,“消息丢弃”为0.
到此,整个离线消息接收功能测试全部完成。