|
@@ -297,7 +297,6 @@ export default {
|
|
|
startArr: [],
|
|
|
endArr: [],
|
|
|
// mqtt相关
|
|
|
- mqttClient: "",
|
|
|
currentIndex: 0,
|
|
|
modules: [],
|
|
|
autoPlayinterval: "",
|
|
@@ -311,6 +310,17 @@ export default {
|
|
|
voipFlag: true,
|
|
|
inactivityTimer: "",
|
|
|
isInitAlarm: "",
|
|
|
+
|
|
|
+ // mqtt模块
|
|
|
+ mqttClient: null,
|
|
|
+ targetPoints: {},
|
|
|
+ inactivityTimer: null,
|
|
|
+ reconnectTimer: null,
|
|
|
+ reconnectCount: 0,
|
|
|
+ maxReconnectAttempts: 5,
|
|
|
+ isConnecting: false,
|
|
|
+ left: 0,
|
|
|
+ top: 0,
|
|
|
};
|
|
|
},
|
|
|
computed: {},
|
|
@@ -377,147 +387,244 @@ export default {
|
|
|
},
|
|
|
|
|
|
connectMQTT(clientId, devId) {
|
|
|
- const THRESHOLD = 2;
|
|
|
- const params = {
|
|
|
- keepalive: 60,
|
|
|
- clean: true,
|
|
|
- connectTimeout: 30 * 1000,
|
|
|
- clientId:
|
|
|
- "wx_mqtt_" + Math.random().toString(16).substring(2, 8),
|
|
|
- username: "admin",
|
|
|
- password: "public",
|
|
|
- // 微信小程序特定配置
|
|
|
- wsOptions: {
|
|
|
- WebSocket: function (url) {
|
|
|
- return wx.connectSocket({
|
|
|
- url: url,
|
|
|
- header: {
|
|
|
- "content-type": "application/json",
|
|
|
- },
|
|
|
- protocols: ["mqtt"],
|
|
|
- });
|
|
|
+ // 配置常量
|
|
|
+ const CONFIG = {
|
|
|
+ THRESHOLD: 2,
|
|
|
+ RECONNECT_DELAY: 3000, // 重连延迟增加到3秒
|
|
|
+ INACTIVITY_TIMEOUT: 1500,
|
|
|
+ MQTT_PARAMS: {
|
|
|
+ keepalive: 60,
|
|
|
+ clean: true,
|
|
|
+ connectTimeout: 30 * 1000,
|
|
|
+ clientId:
|
|
|
+ "wx_mqtt_" +
|
|
|
+ Math.random().toString(16).substring(2, 10),
|
|
|
+ username: "admin",
|
|
|
+ password: "public",
|
|
|
+ wsOptions: {
|
|
|
+ WebSocket: function (url) {
|
|
|
+ return wx.connectSocket({
|
|
|
+ url: url,
|
|
|
+ header: { "content-type": "application/json" },
|
|
|
+ protocols: ["mqtt"],
|
|
|
+ });
|
|
|
+ },
|
|
|
},
|
|
|
+ rejectUnauthorized: false,
|
|
|
},
|
|
|
- rejectUnauthorized: false, // 仅开发环境使用,生产环境应设为true或移除
|
|
|
};
|
|
|
- let client = "";
|
|
|
- let selectedService = uni.getStorageSync("sercviceChoice");
|
|
|
- if (!selectedService || selectedService == "aloneServe") {
|
|
|
- client = mqtt.connect("wxs://radar-power.cn:8084/mqtt", params);
|
|
|
- }
|
|
|
- // 存储client引用以便后续操作
|
|
|
- this.mqttClient = client;
|
|
|
|
|
|
- client.on("connect", () => {
|
|
|
+ // 清理之前的连接和定时器
|
|
|
+ this.cleanupMQTT();
|
|
|
+
|
|
|
+ // 获取服务选择
|
|
|
+ const selectedService = uni.getStorageSync("sercviceChoice");
|
|
|
+ const serverUrl = "wxs://radar-power.cn:8084/mqtt";
|
|
|
+
|
|
|
+ // 创建连接
|
|
|
+ this.mqttClient = mqtt.connect(serverUrl, CONFIG.MQTT_PARAMS);
|
|
|
+
|
|
|
+ // 连接成功事件
|
|
|
+ this.mqttClient.on("connect", () => {
|
|
|
console.log("MQTT连接成功");
|
|
|
- client.subscribe(`/dev/${clientId}/dsp_data`, (err) => {
|
|
|
- if (err) {
|
|
|
- console.error("订阅失败", err);
|
|
|
- } else {
|
|
|
- console.log(
|
|
|
- `成功订阅设备主题: /dev/${clientId}/dsp_data`
|
|
|
- );
|
|
|
- }
|
|
|
- });
|
|
|
+ this.handleConnectSuccess(clientId);
|
|
|
});
|
|
|
- client.on("disconnect", () => {
|
|
|
- console.log("MQTT不在连接");
|
|
|
+
|
|
|
+ // 断开连接事件
|
|
|
+ this.mqttClient.on("disconnect", () => {
|
|
|
+ console.log("MQTT连接断开");
|
|
|
});
|
|
|
- client.on("error", (err) => {
|
|
|
- // console.error("MQTT连接错误", err);
|
|
|
- setTimeout(() => {
|
|
|
- // console.log("尝试重新连接MQTT...");
|
|
|
- this.connectMQTT(clientId, devId);
|
|
|
- }, 5000);
|
|
|
+
|
|
|
+ // 错误事件
|
|
|
+ this.mqttClient.on("error", (err) => {
|
|
|
+ console.error("MQTT连接错误", err);
|
|
|
+ this.handleReconnect(clientId, devId, CONFIG.RECONNECT_DELAY);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 重连事件
|
|
|
+ this.mqttClient.on("reconnect", () => {
|
|
|
+ console.log("MQTT尝试重新连接");
|
|
|
+ });
|
|
|
+
|
|
|
+ // 关闭事件
|
|
|
+ this.mqttClient.on("close", () => {
|
|
|
+ console.log("MQTT连接已关闭");
|
|
|
+ });
|
|
|
+
|
|
|
+ // 消息事件
|
|
|
+ this.mqttClient.on("message", (topic, message) => {
|
|
|
+ this.handleMessage(topic, message, clientId, CONFIG);
|
|
|
});
|
|
|
+ },
|
|
|
+
|
|
|
+ // 处理连接成功
|
|
|
+ handleConnectSuccess(clientId) {
|
|
|
+ this.mqttClient.subscribe(`/dev/${clientId}/dsp_data`, (err) => {
|
|
|
+ if (err) {
|
|
|
+ console.error("订阅失败", err);
|
|
|
+ } else {
|
|
|
+ console.log(`成功订阅设备主题: /dev/${clientId}/dsp_data`);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 处理MQTT消息
|
|
|
+ handleMessage(topic, message, clientId, CONFIG) {
|
|
|
+ // 清除不活动定时器
|
|
|
+ clearTimeout(this.inactivityTimer);
|
|
|
+ this.inactivityTimer = setTimeout(() => {
|
|
|
+ this.targetPoints = {};
|
|
|
+ console.log("长时间没有点位,清除数据");
|
|
|
+ }, CONFIG.INACTIVITY_TIMEOUT);
|
|
|
+
|
|
|
+ // 验证topic格式
|
|
|
+ const match = topic.match(/^\/dev\/(.+)\/dsp_data$/);
|
|
|
+ if (!match || match[1] !== clientId) return;
|
|
|
+
|
|
|
+ try {
|
|
|
+ const data = JSON.parse(message.toString());
|
|
|
+ this.processTrackerData(data.tracker_targets, CONFIG.THRESHOLD);
|
|
|
+ } catch (e) {
|
|
|
+ console.error("MQTT消息解析失败", e);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 处理追踪器数据
|
|
|
+ processTrackerData(arr, THRESHOLD) {
|
|
|
+ if (!Array.isArray(arr) || arr.length === 0) {
|
|
|
+ this.targetPoints = {};
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const currentIds = new Set();
|
|
|
+ const newTargetPoints = {};
|
|
|
+
|
|
|
+ // 处理每个追踪目标
|
|
|
+ arr.forEach((item) => {
|
|
|
+ if (!Array.isArray(item) || item.length < 4) return;
|
|
|
|
|
|
- client.on("reconnect", () => {
|
|
|
- // console.log("MQTT正在重新连接...");
|
|
|
+ const [x, y, z, id] = item;
|
|
|
+ currentIds.add(id.toString());
|
|
|
+
|
|
|
+ // 处理新点或更新现有点
|
|
|
+ if (!this.targetPoints[id]) {
|
|
|
+ newTargetPoints[id] = this.createNewTargetPoint(
|
|
|
+ x,
|
|
|
+ y,
|
|
|
+ z,
|
|
|
+ id
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ newTargetPoints[id] = this.updateExistingTargetPoint(
|
|
|
+ this.targetPoints[id],
|
|
|
+ x,
|
|
|
+ y,
|
|
|
+ z,
|
|
|
+ THRESHOLD
|
|
|
+ );
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
- client.on("close", () => {
|
|
|
- // console.log("MQTT连接已关闭");
|
|
|
+ // 移除不存在的点
|
|
|
+ Object.keys(this.targetPoints).forEach((id) => {
|
|
|
+ if (!currentIds.has(id)) {
|
|
|
+ delete this.targetPoints[id];
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
- client.on("message", (topic, message) => {
|
|
|
+ // 更新目标点
|
|
|
+ this.targetPoints = { ...this.targetPoints, ...newTargetPoints };
|
|
|
+ this.cleanTargetPoints();
|
|
|
+
|
|
|
+ console.log("当前目标点", this.targetPoints);
|
|
|
+ },
|
|
|
+
|
|
|
+ // 创建新目标点
|
|
|
+ createNewTargetPoint(x, y, z, id) {
|
|
|
+ return {
|
|
|
+ x,
|
|
|
+ y,
|
|
|
+ z,
|
|
|
+ id,
|
|
|
+ displayX: x,
|
|
|
+ displayY: y,
|
|
|
+ lastX: x,
|
|
|
+ lastY: y,
|
|
|
+ };
|
|
|
+ },
|
|
|
+
|
|
|
+ // 更新现有目标点
|
|
|
+ updateExistingTargetPoint(existingPoint, x, y, z, THRESHOLD) {
|
|
|
+ const dx = x - existingPoint.lastX;
|
|
|
+ const dy = y - existingPoint.lastY;
|
|
|
+ const distance = Math.sqrt(dx * dx + dy * dy);
|
|
|
+
|
|
|
+ if (distance > THRESHOLD) {
|
|
|
+ return {
|
|
|
+ ...existingPoint,
|
|
|
+ x,
|
|
|
+ y,
|
|
|
+ z,
|
|
|
+ lastX: x,
|
|
|
+ lastY: y,
|
|
|
+ displayX: x,
|
|
|
+ displayY: y,
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ return existingPoint;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 清理目标点数组
|
|
|
+ cleanTargetPoints() {
|
|
|
+ // 如果targetPoints是数组,过滤掉null/undefined
|
|
|
+ if (Array.isArray(this.targetPoints)) {
|
|
|
+ this.targetPoints = this.targetPoints.filter(
|
|
|
+ (item) => item !== null && item !== undefined
|
|
|
+ );
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 处理重连
|
|
|
+ handleReconnect(clientId, devId, delay) {
|
|
|
+ // 使用防抖避免频繁重连
|
|
|
+ if (this.reconnectTimer) {
|
|
|
+ clearTimeout(this.reconnectTimer);
|
|
|
+ }
|
|
|
+
|
|
|
+ this.reconnectTimer = setTimeout(() => {
|
|
|
+ const storedDevId = uni.getStorageSync("devIdDetail");
|
|
|
+ const storedClientId = uni.getStorageSync("clientIDetail");
|
|
|
+
|
|
|
+ if (storedClientId && storedDevId) {
|
|
|
+ console.log("尝试重新连接MQTT...");
|
|
|
+ this.connectMQTT(storedClientId, storedDevId);
|
|
|
+ }
|
|
|
+ }, delay);
|
|
|
+ },
|
|
|
+
|
|
|
+ // 清理MQTT资源
|
|
|
+ cleanupMQTT() {
|
|
|
+ // 清理定时器
|
|
|
+ if (this.inactivityTimer) {
|
|
|
clearTimeout(this.inactivityTimer);
|
|
|
- this.inactivityTimer = setTimeout(() => {
|
|
|
- this.targetPoints = {};
|
|
|
- console.log("长时间没有点位,消除");
|
|
|
- }, 1500);
|
|
|
+ this.inactivityTimer = null;
|
|
|
+ }
|
|
|
|
|
|
- const match = topic.match(/^\/dev\/(.+)\/dsp_data$/);
|
|
|
- if (!match) return;
|
|
|
- const msgDevId = match[1];
|
|
|
- console.log(msgDevId, 9999999999);
|
|
|
- if (msgDevId !== clientId) return; // 只处理当前设备
|
|
|
+ if (this.reconnectTimer) {
|
|
|
+ clearTimeout(this.reconnectTimer);
|
|
|
+ this.reconnectTimer = null;
|
|
|
+ }
|
|
|
|
|
|
+ // 断开旧连接
|
|
|
+ if (this.mqttClient) {
|
|
|
try {
|
|
|
- const data = JSON.parse(message.toString());
|
|
|
- // console.log(data, 9999);
|
|
|
- const arr = data.tracker_targets;
|
|
|
- this.left = arr[0];
|
|
|
- this.top = arr[1];
|
|
|
- if (arr.length > 0) {
|
|
|
- const currentIds = new Set();
|
|
|
- arr.forEach((item) => {
|
|
|
- if (item.length < 4) return;
|
|
|
- const [x, y, z, id] = item;
|
|
|
- currentIds.add(id);
|
|
|
- console.log(currentIds, 9999);
|
|
|
- if (!(id in this.targetPoints)) {
|
|
|
- this.targetPoints[id] = {
|
|
|
- x,
|
|
|
- y,
|
|
|
- z,
|
|
|
- id,
|
|
|
- displayX: x,
|
|
|
- displayY: y,
|
|
|
- lastX: x,
|
|
|
- lastY: y,
|
|
|
- };
|
|
|
- }
|
|
|
- // 去抖动
|
|
|
- const dx = x - this.targetPoints[id].lastX;
|
|
|
- const dy = y - this.targetPoints[id].lastY;
|
|
|
- if (Math.sqrt(dx * dx + dy * dy) > THRESHOLD) {
|
|
|
- this.targetPoints[id].x = x;
|
|
|
- this.targetPoints[id].y = y;
|
|
|
- this.targetPoints[id].z = z;
|
|
|
- this.targetPoints[id].lastX = x;
|
|
|
- this.targetPoints[id].lastY = y;
|
|
|
- this.targetPoints[id].displayX = x;
|
|
|
- this.targetPoints[id].displayY = y;
|
|
|
- }
|
|
|
- });
|
|
|
- this.targetPoints.forEach((item) => {
|
|
|
- const id = item.id;
|
|
|
- console.log(item, id, 999999);
|
|
|
- if (!currentIds.has(id)) {
|
|
|
- delete this.targetPoints[id];
|
|
|
- }
|
|
|
- });
|
|
|
- let cleanPoints = JSON.parse(
|
|
|
- JSON.stringify(this.targetPoints)
|
|
|
- );
|
|
|
- this.targetPoints = cleanPoints.filter(
|
|
|
- (item) => item !== null
|
|
|
- );
|
|
|
- // this.targetPoints = this.targetPoints.filter(
|
|
|
- // (item, index, self) =>
|
|
|
- // self.findIndex((i) => i.id === item.id) ===
|
|
|
- // index
|
|
|
- // );
|
|
|
- console.log("🚀🚀🚀🚀targets", this.targetPoints);
|
|
|
- } else {
|
|
|
- this.targetPoints.forEach(
|
|
|
- (key) => delete this.targetPoints[key]
|
|
|
- );
|
|
|
- }
|
|
|
+ this.mqttClient.end();
|
|
|
+ this.mqttClient = null;
|
|
|
} catch (e) {
|
|
|
- // console.error("MQTT消息解析失败", e);
|
|
|
+ console.warn("断开旧连接时发生错误", e);
|
|
|
}
|
|
|
- });
|
|
|
+ }
|
|
|
},
|
|
|
|
|
|
parseDeviceItem(devItemStr) {
|
|
@@ -768,11 +875,17 @@ export default {
|
|
|
}月${now.getDate().toString().padStart(2, "0")}日`;
|
|
|
},
|
|
|
},
|
|
|
+ onShow() {
|
|
|
+ let devIdDetail = uni.getStorageSync("devIdDetail");
|
|
|
+ let clientIDetail = uni.getStorageSync("clientIDetail");
|
|
|
+ this.connectMQTT(clientIDetail, devIdDetail);
|
|
|
+ console.log(devIdDetail, clientIDetail, 999999);
|
|
|
+ },
|
|
|
onLoad(options) {
|
|
|
const devItem = this.parseDeviceItem(options.devItem);
|
|
|
const { devId, clientId } = devItem;
|
|
|
this.isInitAlarm = true;
|
|
|
- this.connectMQTT(clientId, devId);
|
|
|
+ // this.connectMQTT(clientId, devId);
|
|
|
this.getFrequency(devId);
|
|
|
this.getdevInfo(devId);
|
|
|
this.getdevRoomInfo(devId);
|
|
@@ -783,15 +896,19 @@ export default {
|
|
|
},
|
|
|
onUnload() {
|
|
|
this.isInitAlarm = false;
|
|
|
- clearInterval(this.autoPlayinterval);
|
|
|
- clearInterval(this.inactivityTimer);
|
|
|
+ this.inactivityTimer = null;
|
|
|
+ this.autoPlayinterval = null;
|
|
|
if (this.mqttClient) {
|
|
|
+ this.cleanupMQTT();
|
|
|
this.mqttClient.end();
|
|
|
}
|
|
|
},
|
|
|
onHide() {
|
|
|
+ this.inactivityTimer = null;
|
|
|
+ this.autoPlayinterval = null;
|
|
|
this.isInitAlarm = false;
|
|
|
if (this.mqttClient) {
|
|
|
+ this.cleanupMQTT();
|
|
|
this.mqttClient.end();
|
|
|
}
|
|
|
},
|