From 520d6b2b1adc8961a3e3472ee592017dd4cd5d1c Mon Sep 17 00:00:00 2001 From: fengerli <528575642@qq.com> Date: Thu, 4 Sep 2025 13:35:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Emqtt=E6=96=87=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E8=AE=A2=E9=98=85=E8=AE=BE=E5=A4=87=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 2 +- package.json | 1 + src/utils/mqtt.ts | 265 ++++++++++++++++++ src/views/controlCenter/6170/index.vue | 132 ++++++++- .../controlCenter/controlPanel/index.vue | 2 - src/views/demo/demo/index.vue | 254 ----------------- src/views/demo/tree/index.vue | 259 ----------------- 7 files changed, 393 insertions(+), 522 deletions(-) create mode 100644 src/utils/mqtt.ts delete mode 100644 src/views/demo/demo/index.vue delete mode 100644 src/views/demo/tree/index.vue diff --git a/.env.development b/.env.development index bfe0359..5642af4 100644 --- a/.env.development +++ b/.env.development @@ -6,7 +6,7 @@ VITE_APP_ENV = 'development' # 开发环境 # VITE_APP_BASE_API = 'http://47.120.79.150/backend' -VITE_APP_BASE_API = 'http://192.168.110.54:8000' +VITE_APP_BASE_API = 'http://192.168.2.23:8000' # VITE_APP_BASE_API = 'http://localhost:8000' diff --git a/package.json b/package.json index 1655330..337738d 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "jsencrypt": "3.3.2", "mitt": "^3.0.1", "nprogress": "0.2.0", + "paho-mqtt": "^1.1.0", "pinia": "3.0.2", "qrcode-vue3": "^1.7.1", "screenfull": "6.0.2", diff --git a/src/utils/mqtt.ts b/src/utils/mqtt.ts new file mode 100644 index 0000000..b032c2a --- /dev/null +++ b/src/utils/mqtt.ts @@ -0,0 +1,265 @@ +import { ref, onUnmounted } from 'vue'; // 修复:导入必要的Vue API +import * as Paho from 'paho-mqtt'; + +// MQTT消息类型定义 +export interface MqttMessage { + topic: string; + payload: string | ArrayBuffer; + qos: number; + retained: boolean; + time: Date; +} + +// 订阅选项 +export interface SubscribeOptions { + qos: 0 | 1 | 2; +} + +// MQTT配置信息 +const MQTT_CONFIG = { + // 连接地址(添加协议类型) + protocol: 'ws', // 关键:明确协议(ws或wss) + host: '47.120.79.150', + port: 9083, + // 认证信息 + username: 'admin', + password: '#YtvpSfCNG', + // 客户端ID(添加时间戳确保唯一性) + clientId: `vue3-mqtt-client-${Date.now()}-${Math.random().toString(36).substring(2, 10)}`, + // 连接选项 + cleanSession: true, + keepAliveInterval: 60, + reconnect: true, +}; + +// MQTT客户端组合式API +export function useMqtt() { + // 客户端实例 + let client: Paho.Client | null = null; + + // 状态管理(修复:已导入ref) + const connected = ref(false); + const connecting = ref(false); + const error = ref(null); + const messages = ref([]); + const subscribedTopics = ref([]); + + // 事件回调 + const connectCallbacks: (() => void)[] = []; + const messageCallbacks: ((message: MqttMessage) => void)[] = []; + const errorCallbacks: ((err: Error) => void)[] = []; + const disconnectCallbacks: (() => void)[] = []; + + // 修复:移除无用的p0参数,connect方法不接受回调(通过onConnect注册) + const connect = () => { + if (connected.value || connecting.value) return; + connecting.value = true; + error.value = null; + + try { + // 创建客户端实例(添加协议参数) + client = new Paho.Client( + MQTT_CONFIG.host, + MQTT_CONFIG.port, + MQTT_CONFIG.clientId + ); + + // 设置连接选项 + const connectOptions: Paho.ConnectOptions = { + userName: MQTT_CONFIG.username, + password: MQTT_CONFIG.password, + cleanSession: MQTT_CONFIG.cleanSession, + keepAliveInterval: MQTT_CONFIG.keepAliveInterval, + reconnect: MQTT_CONFIG.reconnect, + + // 连接成功回调 + onSuccess: () => { + console.log('MQTT连接成功'); + connected.value = true; + connecting.value = false; + connectCallbacks.forEach(cb => cb()); // 触发所有连接成功回调 + }, + + // 连接失败回调 + onFailure: (err) => { + console.error('MQTT连接失败:', err); + error.value = new Error(err.errorMessage || '连接失败'); + connected.value = false; + connecting.value = false; + errorCallbacks.forEach(cb => cb(error.value!)); + } + }; + + // 设置客户端回调 + client.onConnectionLost = (responseObject) => { + if (responseObject.errorCode !== 0) { + console.error('连接丢失:', responseObject.errorMessage); + error.value = new Error(responseObject.errorMessage || '连接丢失'); + errorCallbacks.forEach(cb => cb(error.value!)); + } + + connected.value = false; + connecting.value = false; + disconnectCallbacks.forEach(cb => cb()); + }; + + // 消息接收回调 + client.onMessageArrived = (message) => { + const newMessage: MqttMessage = { + topic: message.destinationName, + payload: message.payloadString || message.payloadBytes, + qos: message.qos, + retained: message.retained, + time: new Date() + }; + + messages.value.push(newMessage); + messageCallbacks.forEach(cb => cb(newMessage)); + }; + + // 连接服务器 + client.connect(connectOptions); + } catch (err) { + console.error('MQTT连接异常:', err); + error.value = err as Error; + connected.value = false; + connecting.value = false; + errorCallbacks.forEach(cb => cb(error.value!)); + } + }; + + // 断开连接 + const disconnect = () => { + if (!client || !connected.value) return; + + client.disconnect(); + client = null; + connected.value = false; + subscribedTopics.value = []; + disconnectCallbacks.forEach(cb => cb()); + }; + + // 订阅主题 + const subscribe = (topic: string, options: SubscribeOptions): Promise => { + return new Promise((resolve, reject) => { + if (!client || !connected.value) { + reject(new Error('未连接到MQTT服务器')); + return; + } + + if (subscribedTopics.value.includes(topic)) { + resolve(); + return; + } + + client.subscribe(topic, { + qos: options.qos, + onSuccess: () => { + console.log(`订阅主题成功: ${topic}`); + subscribedTopics.value.push(topic); + resolve(); + }, + onFailure: (err) => { + console.error(`订阅主题失败: ${topic}`, err); + reject(new Error(err.errorMessage || `订阅主题 ${topic} 失败`)); + } + }); + }); + }; + + // 取消订阅 + const unsubscribe = (topic: string): Promise => { + return new Promise((resolve, reject) => { + if (!client || !connected.value) { + reject(new Error('未连接到MQTT服务器')); + return; + } + + if (!subscribedTopics.value.includes(topic)) { + resolve(); + return; + } + + client.unsubscribe(topic, { + onSuccess: () => { + console.log(`取消订阅主题成功: ${topic}`); + subscribedTopics.value = subscribedTopics.value.filter(t => t !== topic); + resolve(); + }, + onFailure: (err) => { + console.error(`取消订阅主题失败: ${topic}`, err); + reject(new Error(err.errorMessage || `取消订阅主题 ${topic} 失败`)); + } + }); + }); + }; + + // 发布消息 + const publish = ( + topic: string, + payload: string | ArrayBuffer, + options: { qos: 0 | 1 | 2; retained?: boolean } + ): Promise => { + return new Promise((resolve, reject) => { + if (!client || !connected.value) { + reject(new Error('未连接到MQTT服务器')); + return; + } + + if (!topic) { + reject(new Error('主题不能为空')); + return; + } + + const message = new Paho.Message( + typeof payload === 'string' ? payload : payload.toString() + ); + + message.destinationName = topic; + message.qos = options.qos; + message.retained = options.retained ?? false; + + client.send(message); + resolve(); + }); + }; + + // 事件注册 + const onConnect = (callback: () => void) => { + connectCallbacks.push(callback); + }; + + const onMessage = (callback: (message: MqttMessage) => void) => { + messageCallbacks.push(callback); + }; + + const onError = (callback: (err: Error) => void) => { + errorCallbacks.push(callback); + }; + + const onDisconnect = (callback: () => void) => { + disconnectCallbacks.push(callback); + }; + + // 组件卸载时断开连接 + onUnmounted(() => { + disconnect(); + }); + + return { + connected, + connecting, + error, + messages, + subscribedTopics, + connect, + disconnect, + subscribe, + unsubscribe, + publish, + onConnect, + onMessage, + onError, + onDisconnect + }; +} diff --git a/src/views/controlCenter/6170/index.vue b/src/views/controlCenter/6170/index.vue index f7b4e72..6606d24 100644 --- a/src/views/controlCenter/6170/index.vue +++ b/src/views/controlCenter/6170/index.vue @@ -125,6 +125,7 @@ @@ -800,4 +920,4 @@ onMounted(() => { } } } - \ No newline at end of file + diff --git a/src/views/controlCenter/controlPanel/index.vue b/src/views/controlCenter/controlPanel/index.vue index fd94f1e..a8578ef 100644 --- a/src/views/controlCenter/controlPanel/index.vue +++ b/src/views/controlCenter/controlPanel/index.vue @@ -301,8 +301,6 @@ const resetQuery = () => { /** 设备控制跳转 */ const handleControl = (row: any) => { - console.log(row,'row1111'); - const deviceId = row.id; router.push('/controlCenter/6170/' + deviceId); }; diff --git a/src/views/demo/demo/index.vue b/src/views/demo/demo/index.vue deleted file mode 100644 index 06da4cf..0000000 --- a/src/views/demo/demo/index.vue +++ /dev/null @@ -1,254 +0,0 @@ - - - diff --git a/src/views/demo/tree/index.vue b/src/views/demo/tree/index.vue deleted file mode 100644 index ef923be..0000000 --- a/src/views/demo/tree/index.vue +++ /dev/null @@ -1,259 +0,0 @@ - - -