feat(mqtt): 增加设备离线遗言消息及主动断开时上报离线状态
- 连接时设置遗嘱消息(will message),主题为设备状态,payload 为包含设备序列号和离线状态的 JSON - 主动断开连接时,先发布一条离线消息,确保服务端即时感知设备下线 - 网络恢复时,自动尝试 MQTT 重连
This commit is contained in:
@@ -138,6 +138,17 @@ public class MqttManager {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建设备离线遗言消息 JSON
|
||||
*/
|
||||
private byte[] buildWillPayload() {
|
||||
String sn = DeviceManagerService.getInstance().getSerial();
|
||||
if (TextUtils.isEmpty(sn)) {
|
||||
sn = "";
|
||||
}
|
||||
return ("{\"sn\":\"" + sn + "\",\"status\":\"offline\"}").getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立 MQTT 连接(异步,断线后自动重连)
|
||||
*/
|
||||
@@ -176,6 +187,12 @@ public class MqttManager {
|
||||
|
||||
mMqttClient.connectWith()
|
||||
.keepAlive(30)
|
||||
.willPublish()
|
||||
.topic(MQTT_TOPIC_STATUS)
|
||||
.payload(buildWillPayload())
|
||||
.qos(com.hivemq.client.mqtt.datatypes.MqttQos.AT_LEAST_ONCE)
|
||||
.retain(false)
|
||||
.applyWillPublish()
|
||||
.send()
|
||||
.whenComplete((connAck, throwable) -> {
|
||||
if (throwable != null) {
|
||||
@@ -240,7 +257,7 @@ public class MqttManager {
|
||||
};
|
||||
|
||||
/**
|
||||
* 断开 MQTT 连接(主动断开,不会触发自动重连)
|
||||
* 断开 MQTT 连接(主动断开,先发离线消息再断连,不会触发遗言)
|
||||
*/
|
||||
public void disconnect() {
|
||||
// 标记主动断开,重连任务与断线监听均据此跳过重连
|
||||
@@ -248,7 +265,13 @@ public class MqttManager {
|
||||
mReconnectHandler.removeCallbacks(mReconnectRunnable);
|
||||
stopHeartbeat();
|
||||
try {
|
||||
if (mMqttClient != null) {
|
||||
if (mMqttClient != null && mConnected) {
|
||||
// 主动上报离线消息,确保服务端即时感知设备下线
|
||||
String sn = DeviceManagerService.getInstance().getSerial();
|
||||
if (!TextUtils.isEmpty(sn)) {
|
||||
String offlinePayload = "{\"sn\":\"" + sn + "\",\"status\":\"offline\"}";
|
||||
publish(MQTT_TOPIC_STATUS, offlinePayload);
|
||||
}
|
||||
mMqttClient.disconnect();
|
||||
mMqttClient = null;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.ttstd.dialer.base.BaseService;
|
||||
import com.ttstd.dialer.bean.req.SnLocationReq;
|
||||
import com.ttstd.dialer.config.CommonConfig;
|
||||
import com.ttstd.dialer.manager.ContactSyncManager;
|
||||
import com.ttstd.dialer.manager.MqttManager;
|
||||
import com.ttstd.dialer.utils.ApkUtils;
|
||||
import com.ttstd.dialer.utils.Logger;
|
||||
import com.ttstd.dialer.utils.SystemUtils;
|
||||
@@ -61,6 +62,8 @@ public class MainService extends BaseService implements NetworkUtils.OnNetworkSt
|
||||
public void onConnected(NetworkUtils.NetworkType networkType) {
|
||||
Logger.e(TAG, "onConnected: networkType = " + networkType);
|
||||
ContactSyncManager.getInstance(this).syncPendingContacts();
|
||||
// 网络恢复后立刻尝试 MQTT 重连
|
||||
MqttManager.getInstance().connect();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
Reference in New Issue
Block a user