diff --git a/app/src/main/java/com/ttstd/dialer/manager/MqttManager.java b/app/src/main/java/com/ttstd/dialer/manager/MqttManager.java index 41a8900..a7d556e 100644 --- a/app/src/main/java/com/ttstd/dialer/manager/MqttManager.java +++ b/app/src/main/java/com/ttstd/dialer/manager/MqttManager.java @@ -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; } diff --git a/app/src/main/java/com/ttstd/dialer/service/main/MainService.java b/app/src/main/java/com/ttstd/dialer/service/main/MainService.java index ccfaf31..9a862b3 100644 --- a/app/src/main/java/com/ttstd/dialer/service/main/MainService.java +++ b/app/src/main/java/com/ttstd/dialer/service/main/MainService.java @@ -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