因为我们要测试断网后qos消息质量的稳定性,所以 cleanSessionFlag(清除会话)必须为false
由于我们要测试中途被mqtt服务器踢掉后的效果,所以示例使用的我的mqtt服务器,您如果有兴趣测试这个的话请修改配置信息为您的服务器
要测试的功能如下图。都是发送20条消息。
2、测试发布QOS1 / QOS2消息
网络正常情况发送,发送qos1消息
打印日志上面红框表示RyanMqtt发布了多少条消息也就是 RyanMqttPublish 接口回复ok的次数,下面表示真正完成发布了多少条
emqx截图,可以看到是20条。但细心的你肯定发现了发送的信息居然不是按顺序来的,这是因为emqx设置订阅的qos2主题,实际显示将会按照qos2完成时间来进行显示
网络正常情况发送,发送qos2消息
模拟发送中途断网,发送qos1消息
这里模拟的意思是:发送第5条的时候把网络硬件进行关闭,发送第10条时启动网络硬件,观察发布消息和实际消息是否对得上号
看上面日志咱们发送了12条,emqx为什么会收到13条呢?
这就是qos1的特性了,允许至少一次的重复接收,咱们断网重新连接的时候根据qos1的特性咱们是可以重新发送的。
模拟发送中途断网,发送qos2消息
这里模拟的意思是:发送第5条的时候把网络硬件进行关闭,发送第10条时启动网络硬件,观察发布消息和实际消息是否对得上号
这里我们就遇到了开头说的ec800m驱动问题,qos2需要较多的网络交互,ec800直接罢工了。
但是等它重连后我们可以发现,qos2的消息依然可以稳定保证只有一次。(之前我自己进行的测试要比这严谨的多,会考虑到多次断网情况等)
模拟发送中途被踢,发送qos1消息
模拟中途被踢:发送20条,在中间的时候手动通过mqtt管理后台把RyanMqtt客户端踢掉
这个测试真考验手速啊,试了4次才成功。
可以看到发送到15条的时候被mqtt服务器给踢掉了,等待重连后可以正常同步
模拟发送中途被踢,发送qos2消息
模拟中途被踢:发送20条,在中间的时候手动通过mqtt管理后台把RyanMqtt客户端踢掉
可以看到发送了15条,但是收到了21条!是bug吗?其实不然,这主要是emqx服务器的策略问题,因为是主动剔除emqx服务器会清除会话上下文,导致qos2消息多接收。
所以说重大风险的环境,一定不要只依靠qos2,太多因素会导致意料之外的结果。一定要通过应用层来保证最终一致性
2、测试订阅QOS1 / QOS2消息
为了方便观察效果,我们使用emqx的脚本功能,给所有发送消息尾部加一个0 - 1000的随机值。方便观察消息接收情况。
脚本如下
网络正常情况接收,接收qos1消息
网络正常情况接收,接收qos2消息
模拟接收中途断网,接收qos1消息
实验条件:使用mqttx上位机发布10条消息,RyanMqtt收到第5条后重启网络硬件,看联网后是否可以接收到消息
模拟接收中途断网,接收qos2消息
实验条件:使用mqttx上位机发布10条消息,RyanMqtt收到第5条后重启网络硬件,看联网后是否可以接收到消息
模拟接收中途被踢,接收qos1消息
模拟接收中途被踢,接收qos2消息
实验条件:我使用mqttx的自动发送功能,一秒发一条。发送20条消息,当发送5 - 10条后从emqx服务器剔除RyanMqtt客户端
尴尬的发现没法测试,上面测试发布消息剔除的时候说过emqx服务器的剔除会清除会话信息,清除后会话信息,虽然RyanMqtt依然保留着订阅主题信息,但是emq服务器的订阅信息不存在了。
所以不管有没有使能clearSession,都非常推荐在连接成功回调函数中订阅主题。