问题描述
在springboot 中用spring-integration-mqtt 连接 MQTT Broker,如果 MQTT Broker长时间重启或主动踢掉客户端连接,当 MQTT Broker重新启动后,客户端主动重连后,不会重新订阅之前的topic
解决办法
1、定义一个重连成功的事件
import org.springframework.integration.mqtt.event.MqttIntegrationEvent;
/**
* @author Gary Russell
* @since 4.2.2
*
*/
@SuppressWarnings("serial")
public class MqttReconnectSuccessEvent extends MqttIntegrationEvent {
private final String message;
public MqttReconnectSuccessEvent(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return this.message;
}
@Override
public String toString() {
return "MqttReconnectSuccessEvent [message=" + this.message + ", source=" + source + "]";
}
}
2、修改 MqttPahoMessageDrivenChannelAdapter 类源码 一种方法就是下载spring-integration-mqtt的源码改完后重新打包,并引用新的包,另一种就是把MqttPahoMessageDrivenChannelAdapter类的源码拷贝到我们的项目里,直接在里面改。 修改MqttPahoMessageDrivenChannelAdapter里的public void connectComplete(boolean reconnect, String serverURI)方法。
/**
* 重新此方法,在重连成功后通知出去了
*
* @param reconnect If true, the connection was the result of automatic reconnect.
* @param serverURI The server URI that the connection was made to.
*/
@Override
public void connectComplete(boolean reconnect, String serverURI) {
if (!reconnect) {
subscribe();
} else {
logger.debug("重连成功");
ApplicationEventPublisher applicationEventPublisher = getApplicationEventPublisher();
if (applicationEventPublisher != null) {
applicationEventPublisher.publishEvent(new MqttReconnectSuccessEvent(this, "重连成功"));
}
}
}
3、监听MqttReconnectSuccessEvent事件
/**
* 处理重连不订阅topic的问题
* @param event
*/
@EventListener
public void handleMqttReconnectSuccessEvent(MqttReconnectSuccessEvent event) {
MqttPahoMessageDrivenChannelAdapter adapter = (MqttPahoMessageDrivenChannelAdapter) event.getSource();
String[] topics = adapter.getTopic();
if (topics != null) {
adapter.removeTopic(topics);
adapter.addTopic(topics);
}
log.info("重新订阅topic成功");
}
此处需要先把之前订阅的topic取消订阅,因为之前的topic数据一直保存在内存中的。
通过上面这样就可以解决在springboot中用spring-integration-mqtt连接MQTT服务重连成功后不重新订阅topic的问题。