MQTT断线重连及订阅消息恢复

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

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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值