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 消息传输协议(一)

你可能感兴趣的:(笔记,java)