|
@@ -13,7 +13,7 @@ class MqttService {
|
|
|
return MqttService.instance;
|
|
|
}
|
|
|
|
|
|
- // 连接 CMD
|
|
|
+ // ---------------- 连接 CMD ----------------
|
|
|
connectCmd(userId) {
|
|
|
if (this.cmdConnected && this.cmdClient) {
|
|
|
console.log("CMD MQTT 已连接,复用现有实例");
|
|
@@ -31,45 +31,24 @@ class MqttService {
|
|
|
|
|
|
// 默认订阅 CMD 主题
|
|
|
const topic = `/mps/wx_${userId}/notice`;
|
|
|
- this.subscribe('CMD', topic, (msg) => {
|
|
|
- console.log('CMD 消息:', msg);
|
|
|
- });
|
|
|
-
|
|
|
- // 打印订阅成功
|
|
|
- console.log(`✅ CMD MQTT 主题已订阅成功: ${topic}`);
|
|
|
+ this.subscribe('CMD', topic, (msg) => console.log('CMD 消息:', msg));
|
|
|
|
|
|
uni.$emit('mqtt-ready', this.cmdClient);
|
|
|
return client;
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- // 连接 DATA
|
|
|
+ // ---------------- 连接 DATA ----------------
|
|
|
connectData(userId) {
|
|
|
- uni.showToast({
|
|
|
- title: "平台连接中...",
|
|
|
- icon: "loading",
|
|
|
- duration: 1000, //持续的时间
|
|
|
- });
|
|
|
+
|
|
|
if (this.dataConnected && this.dataClient) {
|
|
|
console.log("DATA MQTT 已连接,复用现有实例");
|
|
|
return Promise.resolve(this.dataClient);
|
|
|
}
|
|
|
+ uni.showToast({ title: "平台连接中...", icon: "loading", duration: 1000 });
|
|
|
|
|
|
const brokerName = 'DATA';
|
|
|
-
|
|
|
- let url = ""
|
|
|
- // if (__wxConfig.envVersion == 'develop') {
|
|
|
- // url = 'wxs://data.radar-power.asia:8084/mqtt/'
|
|
|
- // }
|
|
|
-
|
|
|
- // if (__wxConfig.envVersion == 'trial') {
|
|
|
- // url = 'wxs://data.radar-power.cn/mqtt/';
|
|
|
- // }
|
|
|
- // if (__wxConfig.envVersion == 'release') {
|
|
|
- // url = 'wxs://data.radar-power.cn/mqtt/';
|
|
|
- // }
|
|
|
- url = 'wxs://data.radar-power.cn/mqtt/';
|
|
|
-
|
|
|
+ const url = 'wxs://data.radar-power.cn/mqtt/';
|
|
|
const clientId = `xcx_mqtt_data1_${userId}_${Date.now()}`;
|
|
|
|
|
|
return this.connectToBroker(brokerName, { url, clientId, username: 'lnradar', password: 'lnradar' })
|
|
@@ -81,7 +60,7 @@ class MqttService {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- // 内部通用连接方法(多连接管理)
|
|
|
+ // ---------------- 内部通用连接方法 ----------------
|
|
|
connectToBroker(brokerName, config) {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
if (this.connections.has(brokerName)) {
|
|
@@ -96,7 +75,7 @@ class MqttService {
|
|
|
clientId: config.clientId,
|
|
|
username: config.username,
|
|
|
password: config.password,
|
|
|
- reconnectPeriod: config.reconnectPeriod || 5000,
|
|
|
+ reconnectPeriod: config.reconnectPeriod || 500,
|
|
|
wsOptions: {
|
|
|
WebSocket: url => wx.connectSocket({
|
|
|
url,
|
|
@@ -109,16 +88,27 @@ class MqttService {
|
|
|
const connection = {
|
|
|
client,
|
|
|
connected: false,
|
|
|
- subscriptions: new Map(),
|
|
|
+ subscriptions: new Map(), // topic => [callbacks]
|
|
|
};
|
|
|
this.connections.set(brokerName, connection);
|
|
|
|
|
|
+ // ---------------- 连接成功 ----------------
|
|
|
client.on('connect', () => {
|
|
|
console.log(`${brokerName} MQTT 连接成功`);
|
|
|
connection.connected = true;
|
|
|
+
|
|
|
+ // 重连时恢复所有订阅
|
|
|
+ connection.subscriptions.forEach((callbacks, topic) => {
|
|
|
+ connection.client.subscribe(topic, (err) => {
|
|
|
+ if (err) console.error(`重连订阅失败: ${topic}`, err);
|
|
|
+ else console.log(`✅ 重连订阅成功: ${topic}`);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
resolve(client);
|
|
|
});
|
|
|
|
|
|
+ // ---------------- 连接错误 ----------------
|
|
|
client.on('error', (err) => {
|
|
|
uni.showModal({
|
|
|
title: '提示',
|
|
@@ -127,30 +117,25 @@ class MqttService {
|
|
|
success: (res) => {
|
|
|
if (res.confirm) {
|
|
|
uni.clearStorageSync();
|
|
|
- uni.reLaunch({
|
|
|
- url: "/pagesA/loginNew/loginNew"
|
|
|
- })
|
|
|
- }
|
|
|
- if (res.cancel) {
|
|
|
-
|
|
|
+ uni.reLaunch({ url: "/pagesA/loginNew/loginNew" });
|
|
|
}
|
|
|
}
|
|
|
- })
|
|
|
+ });
|
|
|
console.error(`${brokerName} MQTT 连接错误:`, err);
|
|
|
connection.connected = false;
|
|
|
reject(err);
|
|
|
});
|
|
|
|
|
|
+ // ---------------- 连接断开 ----------------
|
|
|
client.on('close', () => {
|
|
|
- uni.showToast({
|
|
|
- title: `平台已经断开`,
|
|
|
- icon: "none",
|
|
|
- duration: 1500,
|
|
|
- });
|
|
|
+ uni.showToast({ title: `平台已断开`, icon: "none", duration: 1500 });
|
|
|
console.log(`${brokerName} MQTT 断开`);
|
|
|
connection.connected = false;
|
|
|
+ if (brokerName === 'DATA') this.dataConnected = false;
|
|
|
+ if (brokerName === 'CMD') this.cmdConnected = false;
|
|
|
});
|
|
|
|
|
|
+ // ---------------- 接收消息 ----------------
|
|
|
client.on('message', (topic, message) => {
|
|
|
const callbacks = connection.subscriptions.get(topic) || [];
|
|
|
callbacks.forEach(cb => {
|
|
@@ -159,21 +144,21 @@ class MqttService {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- // 连接超时
|
|
|
+ // ---------------- 连接超时 ----------------
|
|
|
setTimeout(() => {
|
|
|
if (!connection.connected) reject(new Error(`${brokerName} 连接超时`));
|
|
|
}, 10000);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- // 发布消息
|
|
|
+ // ---------------- 发布消息 ----------------
|
|
|
publish(clientType, topic, message) {
|
|
|
const client = clientType === 'CMD' ? this.cmdClient : this.dataClient;
|
|
|
if (client) client.publish(topic, message);
|
|
|
else console.warn(`${clientType} MQTT 未连接,无法 publish`);
|
|
|
}
|
|
|
|
|
|
- // 订阅
|
|
|
+ // ---------------- 订阅 ----------------
|
|
|
subscribe(clientType, topic, callback, onSubscribeDone) {
|
|
|
const connection = clientType === 'CMD' ? this.connections.get('CMD') : this.connections.get('DATA');
|
|
|
if (!connection || !connection.connected) {
|
|
@@ -189,10 +174,7 @@ class MqttService {
|
|
|
|
|
|
// 执行订阅
|
|
|
connection.client.subscribe(topic, (err) => {
|
|
|
- if (err) {
|
|
|
- console.error(`Subscribe error on ${clientType}:`, err);
|
|
|
- }
|
|
|
- // 订阅完成回调
|
|
|
+ if (err) console.error(`Subscribe error on ${clientType}:`, err);
|
|
|
if (onSubscribeDone) onSubscribeDone(err);
|
|
|
});
|
|
|
|
|
@@ -200,7 +182,7 @@ class MqttService {
|
|
|
return () => this.unsubscribe(clientType, topic, callback);
|
|
|
}
|
|
|
|
|
|
- // 取消订阅
|
|
|
+ // ---------------- 取消订阅 ----------------
|
|
|
unsubscribe(clientType, topic, callback) {
|
|
|
const connection = clientType === 'CMD' ? this.connections.get('CMD') : this.connections.get('DATA');
|
|
|
if (!connection) return;
|
|
@@ -216,14 +198,28 @@ class MqttService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 断开所有连接
|
|
|
+ // ---------------- 手动恢复订阅 ----------------
|
|
|
+ resubscribeAll(brokerName) {
|
|
|
+ const connection = this.connections.get(brokerName); ``
|
|
|
+ if (!connection || !connection.connected) return;
|
|
|
+
|
|
|
+ connection.subscriptions.forEach((callbacks, topic) => {
|
|
|
+ connection.client.subscribe(topic, (err) => {
|
|
|
+ if (err) console.error(`手动恢复订阅失败: ${topic}`, err);
|
|
|
+ else console.log(`✅ 手动恢复订阅成功: ${topic}`);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // ---------------- 断开连接 ----------------
|
|
|
disconnectAll() {
|
|
|
if (this.cmdClient) { this.cmdClient.end(true); this.cmdClient = null; this.cmdConnected = false; }
|
|
|
if (this.dataClient) { this.dataClient.end(true); this.dataClient = null; this.dataConnected = false; }
|
|
|
- this.connections.forEach(conn => conn.client.end());
|
|
|
+ this.connections.forEach(conn => conn.client.end(true));
|
|
|
this.connections.clear();
|
|
|
console.log('所有 MQTT 连接已关闭');
|
|
|
}
|
|
|
+
|
|
|
disconnectData() {
|
|
|
if (this.dataClient) {
|
|
|
this.dataClient.end(true);
|