mqtt架构修改

master
xce 2026-01-18 19:11:45 +08:00
parent 997cd9426b
commit 001ad6c071
6 changed files with 109 additions and 31 deletions

29
App.vue
View File

@ -3,6 +3,8 @@ import config from './config'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import mqttUtil from '@/utils/mqtt' import mqttUtil from '@/utils/mqtt'
import {startMqttOnlinePing, stopMqttOnlinePing} from "./utils/mqtt"; import {startMqttOnlinePing, stopMqttOnlinePing} from "./utils/mqtt";
import {batchSubscribe} from "./api/system/mqtt";
import store from "store";
export default { export default {
globalData: { globalData: {
@ -107,8 +109,27 @@ export default {
console.error('MQTT连接失败') console.error('MQTT连接失败')
return return
} }
var clientId = mqttUtil.getMqttState().clientId;
const subscribeList = [
`frontend/${clientId}/dtu/864865085016294/listener`,
`frontend/${clientId}/dtu/864536071808560/listener`,
`frontend/${clientId}/dtu/864865085008135/listener`,
`frontend/${clientId}/dtu/862538065276939/listener`
];
if (store.getters && store.getters.name === 'admin') {
subscribeList.push(`frontend/${clientId}/dtu/862538065276061/listener`);
}
this.globalData.mqtt.subscribeList = subscribeList || []
batchSubscribe({clientId: clientId}).then((result) => {
if (result.code === 200) {
console.info(`设备列表订阅成功:${subscribeList}`)
}
})
// ========== localStorage ==========
uni.setStorageSync('mqtt_subscribe_list', subscribeList || [])
const subscribeList = this.globalData.mqtt.subscribeList
if (subscribeList.length > 0) { if (subscribeList.length > 0) {
mqttUtil.updateSubscribeList(subscribeList) mqttUtil.updateSubscribeList(subscribeList)
console.log('恢复MQTT订阅列表', subscribeList) console.log('恢复MQTT订阅列表', subscribeList)
@ -116,12 +137,10 @@ export default {
uni.setStorageSync('mqtt_subscribe_list', subscribeList) uni.setStorageSync('mqtt_subscribe_list', subscribeList)
} }
}, },
loginSuccess(token, subscribeList) { loginSuccess(token) {
this.globalData.mqtt.hasLogin = true this.globalData.mqtt.hasLogin = true
this.globalData.mqtt.token = token this.globalData.mqtt.token = token
this.globalData.mqtt.subscribeList = subscribeList || []
// ========== localStorage ==========
uni.setStorageSync('mqtt_subscribe_list', subscribeList || [])
this.reconnectMqtt() this.reconnectMqtt()
console.log('登录成功MQTT已初始化') console.log('登录成功MQTT已初始化')
}, },

49
api/system/mqtt.js Normal file
View File

@ -0,0 +1,49 @@
import request from '@/utils/request'
export function subscribe(query) {
return request({
url: '/api/mqtt/single',
method: 'post',
params: query
})
}
export function unsubscribe(query) {
return request({
url: '/api/mqtt/single',
method: 'delete',
params: query
})
}
export function batchUnsubscribe(query) {
return request({
url: '/api/mqtt/batchUnsubscribe',
method: 'delete',
params: query
})
}
export function batchSubscribe(query) {
return request({
url: '/api/mqtt/batchSubscribe',
method: 'post',
params: query
})
}
export function manualReconnect(query) {
return request({
url: '/api/mqtt/reconnect',
method: 'get',
params: query
})
}
export function status() {
return request({
url: '/api/mqtt/batch',
method: 'get'
})
}

View File

@ -117,7 +117,7 @@ const SENSOR_MAP = {
temp1: "201", temp2: "202", temp3: "203", temp4: "204", temp1: "201", temp2: "202", temp3: "203", temp4: "204",
humi1: "101", humi2: "102", humi3: "103", humi4: "104" humi1: "101", humi2: "102", humi3: "103", humi4: "104"
}; };
const MQTT_TOPIC_SUFFIX = { UP: "/up", DOWN: "/down" }; const MQTT_TOPIC_SUFFIX = { UP: "/listener", DOWN: "/control" };
import UniDatetimePicker from "../../uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue"; import UniDatetimePicker from "../../uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue";
import UniPopup from "../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue"; // import UniPopup from "../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue"; //
@ -141,7 +141,7 @@ export default {
return { return {
temp: "", temp: "",
mqttConfig: { mqttConfig: {
subscribeTopic:'/up', subscribeTopic:'/listener',
}, },
value: 1, value: 1,
selectedText: '', selectedText: '',
@ -151,7 +151,7 @@ export default {
range: [], range: [],
agriId:'', agriId:'',
imei:'', imei:'',
publishTopic: '/down', publishTopic: '/control',
title:'', title:'',
message: {}, message: {},
// connected // connected
@ -272,10 +272,11 @@ export default {
}, },
change(e) { change(e) {
this.imei = e; this.imei = e;
var clientId = mqttUtil.getMqttState().clientId;
if ((e === 'A' || e==='B' || e==='C') if ((e === 'A' || e==='B' || e==='C')
&& store.getters && store.getters.name === 'admin' ) { && store.getters && store.getters.name === 'admin' ) {
this.getNewSpecialData(e); this.getNewSpecialData(e);
this.mqttConfig.subscribeTopic = `dtu/862538063921866${MQTT_TOPIC_SUFFIX.UP}`; this.mqttConfig.subscribeTopic = `frontend/${clientId}/dtu/862538063921866${MQTT_TOPIC_SUFFIX.UP}`;
} }
const selectedItem = this.range.find(item => item.value === e); const selectedItem = this.range.find(item => item.value === e);
if (selectedItem) { if (selectedItem) {
@ -284,8 +285,8 @@ export default {
this.title= this.selectedText; this.title= this.selectedText;
if (e !== 'A' && e!=='B' && e!=='C') { if (e !== 'A' && e!=='B' && e!=='C') {
// 使MQTT // 使MQTT
this.publishTopic = `dtu/${this.imei}${MQTT_TOPIC_SUFFIX.DOWN}`; this.publishTopic = `frontend/${clientId}${MQTT_TOPIC_SUFFIX.DOWN}/${this.imei}`;
this.mqttConfig.subscribeTopic = `dtu/${this.imei}${MQTT_TOPIC_SUFFIX.UP}`; this.mqttConfig.subscribeTopic = `frontend/${clientId}/dtu/${this.imei}${MQTT_TOPIC_SUFFIX.UP}`;
var queryParams = { var queryParams = {
imei: this.imei imei: this.imei
} }
@ -489,7 +490,7 @@ export default {
// //
ackMessage(topic, payload) { ackMessage(topic, payload) {
// 1. dtu/xxx/up // 1. frontend/\\w+/control/\\w+"
if (topic !== this.mqttConfig.subscribeTopic) return; if (topic !== this.mqttConfig.subscribeTopic) return;
let msgData = {}; let msgData = {};
// JSON // JSON

View File

@ -52,7 +52,6 @@
import { getCodeImg } from '@/api/login' import { getCodeImg } from '@/api/login'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import UniIcons from "../uni_modules/uni-icons/components/uni-icons/uni-icons.vue"; import UniIcons from "../uni_modules/uni-icons/components/uni-icons/uni-icons.vue";
import store from "../store";
export default { export default {
components: {UniIcons}, components: {UniIcons},
@ -145,13 +144,8 @@
// 864865085016294 // 864865085016294
// 864536071808560 // 864536071808560
// 864865085008135 // 864865085008135
const subscribeList = [`dtu/864865085016294/up`, `dtu/864536071808560/up`,`dtu/864865085008135/up`,`dtu/862538065276939/up`]
if (store.getters && store.getters.name === 'admin') {
subscribeList.push(`dtu/862538065276061/up`);
}
// 4. App.vueloginSuccessMQTT // 4. App.vueloginSuccessMQTT
app.loginSuccess(token, subscribeList) app.loginSuccess(token)
// ========== ========== // ========== ==========
this.$tab.reLaunch('/pages/control/index') this.$tab.reLaunch('/pages/control/index')

View File

@ -5,8 +5,10 @@ import { isHttp, isEmpty } from "@/utils/validate"
import { login, logout, getInfo } from '@/api/login' import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth' import { getToken, setToken, removeToken } from '@/utils/auth'
import defAva from '@/static/images/profile.jpg' import defAva from '@/static/images/profile.jpg'
import {batchUnsubscribe} from "@/api/system/mqtt";
const baseUrl = config.baseUrl const baseUrl = config.baseUrl
import mqttUtil from '@/utils/mqtt';
const user = { const user = {
state: { state: {
@ -92,6 +94,8 @@ const user = {
// 退出系统 // 退出系统
LogOut({ commit, state }) { LogOut({ commit, state }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
batchUnsubscribe({clientId:mqttUtil.getMqttState().clientId}).then(response => {
if (response.code === 200) {
logout(state.token).then(() => { logout(state.token).then(() => {
commit('SET_TOKEN', '') commit('SET_TOKEN', '')
commit('SET_ROLES', []) commit('SET_ROLES', [])
@ -102,6 +106,9 @@ const user = {
}).catch(error => { }).catch(error => {
reject(error) reject(error)
}) })
console.info("取消订阅成功!")
}
})
}) })
} }
} }

View File

@ -10,6 +10,8 @@
// 微信小程序端:引入适配小程序的 mqtt 版本 // 微信小程序端:引入适配小程序的 mqtt 版本
import mqtt from 'mqtt/dist/mqtt' import mqtt from 'mqtt/dist/mqtt'
import {batchUnsubscribe} from "../api/system/mqtt";
import {getToken} from "./auth";
// ===================== MQTT配置暂时写死TODO后续从数据字典获取===================== // ===================== MQTT配置暂时写死TODO后续从数据字典获取=====================
const MQTT_CONFIG = { const MQTT_CONFIG = {
@ -240,7 +242,13 @@ export function disconnectMqtt() {
resetMqttState() resetMqttState()
return true return true
} }
if (getToken()) {
batchUnsubscribe({clientId:mqttState.options.clientId}).then(response => {
if (response.code === 200) {
console.info("取消订阅成功!")
}
})
}
try { try {
mqttState.client.end(true) // 强制断开 mqttState.client.end(true) // 强制断开
resetMqttState() resetMqttState()