SpringBoot 开发之 MQTT 协议客户端断线后自动重连与保留断线时发布的主题消息

1、自动断线机制

使用MQTT自带的 AutomaticReconnect 属性

// 断开后重连,但这个方法并没有重新订阅的机制
// 在尝试重新连接之前,它将首先等待1秒,对于每次失败的重新连接尝试,延迟将加倍,直到达到2分钟,此时延迟将保持在2分钟。
options.setAutomaticReconnect(true);
使用 automaticReconnect 为 true 表示断线自动重连,但仅仅只是重新连接,并不订阅主题;
在 connectComplete 回调函数重新订阅,实现如下:
@Override
public void connectComplete(boolean b, String s) {
    // 客户端连接成功
    CodeUtils.info("[MQTT] 连接成功,重新订阅主题...");
    try {
        client.subscribe(topic, QOS);
    } catch (MqttException e) {
        e.printStackTrace();
    }
}
2、手动设置断线重连

在connectionLost () 回调函数中自定义重新连接

@Override
public void connectionLost(Throwable cause) {
    // 连接断开
    CodeUtils.info("[MQTT] 连接断开,30S之后尝试重连...");
    while(true) {
        try {
            Thread.sleep(30000);
         	// 重新连接
            client.connect(options);
            break;
        } catch (Exception e) {
            e.printStackTrace();
            continue;
        }
    }
}
同方法一,这也只是重新连接,并不重新订阅主题,需手动订阅,如:
@Override
public void connectionLost(Throwable cause) {
   // 连接断开
   CodeUtils.info("[MQTT] 连接断开,30S之后尝试重连...");
   while(true) {
       try {
           Thread.sleep(30000);
        	// 重新连接
           client.connect(options);
           // 重新订阅
           client.subscribe(topic, QOS);
           break;
       } catch (Exception e) {
           e.printStackTrace();
           continue;
       }
   }
}
或者同方法一在 connectComplete 中订阅

3、如何在重连后收到断线时发布的消息

// 保持会话不被清理自动重连后才能收到到主题消息(包括离线时发布的消息)
options.setCleanSession(false); 
cleanSession 为 false 表示断线后会话不会被清除,服务器会保留客户端订阅信息等待客户端重连,在断线期间发布的消息也会保留,当同一客户端重连后会自动订阅原订阅的主题,并且可以订阅到断线时发布的主题消息( 同一clientId 表示同一个客户端 )。

同一个客户端重复 subscribe 一个主题也不会导致收到消息重复。

4* 断线重新连接遇到的问题

在运用过程中,会出现断开连接第一次重连成功后,一直断开连接再重连再断开连接再重连的死循环中

  • 问题原因:
    创建了相同clientid 的MqttClient。
  • 问题解析:
    因为clientid是MqttClient的唯一标识,当重新new上一个clientid相同的MqttClient就会出现重连时创建的MqttClient使程序中初始化时创建的MqttClient断开连接,断开连接后就会回滚到connectionLost方法中,然后此方法中又会继续重连。
  • 解决办法:
    不需要重新new一个MqttClient,只需要调用connect()方法就OK了。

5.回调方法

  • connectionLost() 连接断开回调方法

    connectionLost() 方法实现于 MqttCallback 接口,在客户端连接断开时触发
  • messageArrived() 消息送达回调方法

    messageArrived() 方法实现于 MqttCallback 接口,在客户端收到订阅的消息时触发
  • deliveryComplete() 传送成功回调方法

    deliveryComplete() 方法实现于 MqttCallback 接口,在客户端发送消息至服务器成功时触发
  • connectComplete() 连接成功回调方法

    connectComplete() 方法实现于 MqttCallbackExtended接口,MqttCallbackExtended接口继承 MqttCallback 接口,在客户端与服务器连接成功时触发

上一篇:MQTT 消息发布与订阅 MQTT 消息传输协议(一)

  • 5
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在使用Spring Boot创建MQTT客户端项目,可以通过配置实现MQTT自动重连。具体步骤如下: 1. 在application.properties文件中添加MQTT连接相关配置,例如: ``` spring.mqtt.username=your_username spring.mqtt.password=your_password spring.mqtt.url=tcp://your_mqtt_server_url:1883 spring.mqtt.clientId=your_client_id ``` 2. 在MQTT配置类中添加MQTT连接工厂和消息监听器等相关配置,例如: ``` @Configuration public class MqttConfig { @Autowired private MqttProperties mqttProperties; @Bean public MqttConnectOptions getMqttConnectOptions() { MqttConnectOptions mqttConnectOptions = new MqttConnectOptions(); mqttConnectOptions.setUserName(mqttProperties.getUsername()); mqttConnectOptions.setPassword(mqttProperties.getPassword().toCharArray()); mqttConnectOptions.setServerURIs(new String[]{mqttProperties.getUrl()}); mqttConnectOptions.setKeepAliveInterval(2); mqttConnectOptions.setAutomaticReconnect(true); return mqttConnectOptions; } @Bean public MqttClient getMqttClient() throws MqttException { MqttClient mqttClient = new MqttClient(mqttProperties.getUrl(), mqttProperties.getClientId()); mqttClient.setCallback(new MqttCallback() { @Override public void connectionLost(Throwable throwable) { // 连接丢失后的处理逻辑 } @Override public void messageArrived(String s, MqttMessage mqttMessage) throws Exception { // 消息到达后的处理逻辑 } @Override public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { // 消息发送完成后的处理逻辑 } }); mqttClient.connect(getMqttConnectOptions()); return mqttClient; } @Bean public MqttPahoMessageDrivenChannelAdapter mqttPahoMessageDrivenChannelAdapter() throws MqttException { MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter( mqttProperties.getUrl(), mqttProperties.getClientId(), getMqttClientFactory(), "your_topic"); adapter.setCompletionTimeout(5000); adapter.setConverter(new DefaultPahoMessageConverter()); adapter.setQos(1); return adapter; } @Bean public DefaultMqttPahoClientFactory getMqttClientFactory() { DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory(); factory.setConnectionOptions(getMqttConnectOptions()); return factory; } } ``` 其中,setAutomaticReconnect(true)表示开启MQTT自动重连机制。 3. 在需要使用MQTT的地方注入MqttPahoMessageDrivenChannelAdapter,并调用start()方法启动消息监听器,例如: ``` @Autowired private MqttPahoMessageDrivenChannelAdapter adapter; public void start() { adapter.start(); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值