feat(mqtt): 增加设备离线遗言消息及主动断开时上报离线状态

- 连接时设置遗嘱消息(will message),主题为设备状态,payload 为包含设备序列号和离线状态的 JSON
- 主动断开连接时,先发布一条离线消息,确保服务端即时感知设备下线
- 网络恢复时,自动尝试 MQTT 重连
This commit is contained in:
TongTongStudio
2026-08-09 20:01:41 +08:00
parent 92d7c93a83
commit 3efa751939
2 changed files with 28 additions and 2 deletions

View File

@@ -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;
}

View File

@@ -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