MQTT断线重连及订阅消息恢复
工具
MQTT客户端是用的 paho http://www.eclipse.org/paho/
问题
采用以下配置
connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setConnectionTimeout(10);
connOpts.setKeepAliveInterval(90);
connOpts.setAutomaticReconnect(true);
网络断开后,客户端会进行重连,但是重连之前订阅的主题就失效了,不再接受之前订阅主题的消息。
解决方法
因为配置里将cleanSession 设为 true ,当客户端掉线时 ,服务器端会清除 客户端 session 。 重连后 客户端会有一个新的session。
第一种
把配置里的 cleanSession 设为false,客户端掉线后 服务器端不会清除session,当重连后可以接收之前订阅主题的消息。当客户端上线后会接受到它离线的这段时间的消息
但是这个只是进行了重连,重连后还需要再次发起订阅
对于离线消息为什么不能接收到,我想说的是 你很有可能在再次连接的时候又重新订阅了该topic。这样是接收不到离线消息的。
离线消息是订阅了某个topic的client 在断开连接以后,在接下来又重新连接的时候,任然可以收到在它断开连接的这段时间内,该topic上的消息。这就需要将client的 setCleanSession 设置为false,这样服务器才能保留它的session,再次建立连接的时候,它就会继续使用这个session了。
注意:clientId 是不能更改的。
第二种
通过查看MqttClient的 connect 方法的代码发现 会调到MqttAsyncClient 的connect
public IMqttToken connect(MqttConnectOptions options, Object userContext, IMqttActionListener callback) throws MqttException, MqttSecurityException {
......
//省略
......
if (this.mqttCallback instanceof MqttCallbackExtended) {
connectActionListener.setMqttCallbackExtended((MqttCallbackExtended) this.mqttCallback);
}
comms.setNetworkModuleIndex(0);
connectActionListener.connect();
return userToken;
}
如果我们设置的 mqttClient.setCallback(mqttCallback); mqttCallback实现了 MqttCallbackExtended接口,就会把它设置给connectActionListener,我再来看看MqttCallbackExtended接口。
public interface MqttCallbackExtended extends

本文探讨了MQTT客户端在断线后如何重连并恢复订阅消息的问题。通过设置`cleanSession`为false,客户端可以接收到离线期间的主题消息,但需要重新订阅。另外,实现`MqttCallbackExtended`接口并在连接成功时重新订阅主题也是一种方法。最后,通过深入MQTT源码,找到在连接成功时触发重连回调的方法,解决了重连后无法订阅的问题。
最低0.47元/天 解锁文章
4921

被折叠的 条评论
为什么被折叠?



