MQTT增加用户锁,连接id增加逻辑

main
刘妍 2 months ago
parent 94fa1b4309
commit 14c5a0241f

@ -1,11 +1,19 @@
import { defHttp } from '@/utils/http/axios';
import { StartLiveParams, SetCameraVideoParams, ExchangeCameraParams } from './model/index';
import {
StartLiveParams,
SetCameraVideoParams,
ExchangeCameraParams,
AddOrUpdateRedisUserParams,
} from './model/index';
enum Api {
StartLive = '/api/AirportMaintenance/StartLive',
EndLive = '/api/AirportMaintenance/EndLive',
SetCameraVideo = '/api/AirportMaintenance/SetCameraVideo',
ExchangeCamera = '/api/AirportMaintenance/ExchangeCamera',
GetRedisUser = '/api/AirportMaintenance/GetRedisUser',
GetLockedClients = '/api/AirportMaintenance/GetLockedClients',
AddOrUpdateRedisUser = '/api/AirportMaintenance/AddOrUpdateRedisUser',
}
export const startLive = (params: StartLiveParams) =>
@ -30,3 +38,16 @@ export const exchangeCamera = (params: ExchangeCameraParams) =>
url: Api.ExchangeCamera,
params,
});
export function getRedisUser(id) {
return defHttp.get({ url: Api.GetRedisUser + '?id=' + id });
}
export function getLockedClients(params?: any) {
return defHttp.get({ url: Api.GetLockedClients, params });
}
export const addOrUpdateRedisUser = (params: AddOrUpdateRedisUserParams) =>
defHttp.post({
url: Api.AddOrUpdateRedisUser,
params,
});

@ -20,3 +20,11 @@ export interface ExchangeCameraParams {
position?: number;
camera?: string;
}
export interface AddOrUpdateRedisUserParams {
clientId?: string;
userId?: string;
userName?: string;
connectTime?: string;
isLock?: boolean;
}

@ -1,5 +1,11 @@
import mqtt from 'mqtt';
import { useMessage } from '@/hooks/web/useMessage';
import { getRedisUser, addOrUpdateRedisUser } from '@/api/workmanagement/airportMaintenance';
import { useUserStore } from '@/store/modules/user';
import { timestampToFormattedDate } from '@/utils/index';
const userStore = useUserStore();
const userInfo = userStore.getUserInfo;
const { createMessage } = useMessage();
const connection = {
@ -12,8 +18,8 @@ const connection = {
clean: true,
connectTimeout: 30 * 1000, // ms
reconnectPeriod: 4000, // ms
// clientId: 'mqttx_' + Math.random().toString(16).substring(2, 8),
clientId: 'mqtt_client_1581F8HGX254V00A0BUY',
clientId: '',
// clientId: 'mqtt_client_1581F8HGX254V00A0BUY',
// auth
username: 'sdhc',
password: '',
@ -44,32 +50,41 @@ const handleOnReConnect = () => {
};
// 创建连接函数
const createConnection = (callback?) => {
console.log('创建连接');
// 连接mqtt的时候先用GetRedisUser查一下有没有
// 然后AddOrUpdateRedisUser更新或添加
// 控制的时候先查一下有没有锁定的用户GetLockedClients
try {
getRedisUser(userInfo.id).then((res) => {
console.log(res);
if (res) {
connection.clientId = res.clientId;
} else {
const clientId = 'mqttx_' + Math.random().toString(16).substring(2, 8);
connection.clientId = clientId;
const querys = {
clientId: clientId,
userId: userInfo.id,
userName: userInfo.name,
isLock: false,
connectTime: timestampToFormattedDate(new Date().getTime()),
};
addOrUpdateRedisUser(querys);
}
});
// const clientId = 'mqttx_' + Math.random().toString(16).substring(2, 8);
// connection.clientId = clientId;
const { protocol, host, port, endpoint, ...options } = connection;
const connectUrl = `${protocol}://${host}:${port}${endpoint}`;
client = mqtt.connect(connectUrl, options);
client.on('connect', () => {
// console.log('✅ 已连接');
if(callback){
callback()
}
});
client.on('close', () => {
// console.log('❌ 连接已关闭');
});
client.on('error', (err) => {
// console.error('❌ 出错了:', err);
});
if (client.on) {
}
} catch (error) {
console.log('mqtt.connect error', error);
}
};
const getClient = () => {
if (!client || !client.connected) {
createConnection();
}
// if (!client || !client.connected) {
// createConnection();
// }
return client;
};
// 断开连接
@ -87,20 +102,16 @@ const destroyConnection = () => {
};
// 订阅事件
const clientSubscribe = (topic: string, options?: any) => {
console.log(client);
if (!client || !client.connected) {
createConnection();
}
getClient().subscribe(topic, { qos: 0 }, (error, res) => {
console.log('订阅');
console.log(error, res);
});
// if (!client || !client.connected) {
// createConnection();
// }
getClient().subscribe(topic, { qos: 0 }, (error, res) => {});
};
// 发送消息
const clientPublish = (topic: string, querys: any) => {
if (!client || !client.connected) {
createConnection();
}
// if (!client || !client.connected) {
// createConnection();
// }
getClient().publish(topic, JSON.stringify(querys), { qos: 0 }, (err) => {
if (err) {
console.error('Publish error:', err);
@ -109,12 +120,11 @@ const clientPublish = (topic: string, querys: any) => {
};
// 获取连接状态
const getConnectStatus = () => {
console.log('client',client)
if (!client.connected) {
return false
return false;
}
return true
}
return true;
};
// on 事件
// connect 连接
// reconnect 重新连接
@ -143,18 +153,31 @@ const createSeizeConnection = () => {
console.log('mqtt.connect error', error);
}
};
const getReizeClient = () => {
if (!client_seize || !client_seize.connected) {
createSeizeConnection();
const destroySeizeConnection = () => {
if (client_seize.connected) {
try {
client_seize.end(false, () => {
client_seize = {
connected: false,
};
console.log('Successfully disconnected!');
});
} catch (error) {
console.log('Disconnect failed', error.toString());
}
}
};
const getReizeClient = () => {
// if (!client_seize || !client_seize.connected) {
// createSeizeConnection();
// }
return client_seize;
};
// 订阅事件
const clientReizeSubscribe = (topic: string, options?: any) => {
console.log(client_seize);
if (!client_seize || !client_seize.connected) {
createConnection();
}
// if (!client_seize || !client_seize.connected) {
// createSeizeConnection();
// }
getReizeClient().subscribe(topic, { qos: 0 }, (error, res) => {
console.log('订阅');
console.log(error, res);
@ -162,9 +185,9 @@ const clientReizeSubscribe = (topic: string, options?: any) => {
};
// 发送消息
const clientReizePublish = (topic: string, querys: any) => {
if (!client_seize || !client_seize.connected) {
createConnection();
}
// if (!client_seize || !client_seize.connected) {
// createSeizeConnection();
// }
getReizeClient().publish(topic, JSON.stringify(querys), { qos: 0 }, (err) => {
if (err) {
console.error('Publish error:', err);
@ -179,6 +202,7 @@ export {
clientSubscribe,
clientPublish,
createSeizeConnection,
destroySeizeConnection,
getReizeClient,
clientReizeSubscribe,
clientReizePublish,

@ -53,7 +53,7 @@
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { onMounted, ref, onBeforeUnmount } from 'vue';
import {
SelectComponent,
AirportInformation,
@ -68,7 +68,7 @@
FlyToForm,
} from './index';
import { useMessage } from '@/hooks/web/useMessage';
import { getClient, createConnection, clientSubscribe } from '@/utils/mqtt';
import { getClient, createConnection, clientSubscribe, destroyConnection } from '@/utils/mqtt';
import { buildGUID } from '@/utils/uuid';
import { vDrag } from '@/utils/drag';
@ -80,11 +80,15 @@
name: null,
});
onMounted(() => {
destroyConnection();
createConnection();
setTimeout(() => {
changeSelect();
}, 1000);
});
onBeforeUnmount(() => {
destroyConnection();
});
const changeSelectValue = ref();
//
const airportLiveVisible = ref(true);

@ -47,9 +47,11 @@
if (val.message.data.result == 0) {
createMessage.success('开始直播成功');
player.src('http://175.27.168.120:6012/live/2.flv');
player.play();
} else if (val.message.data.result == 513003) {
createMessage.success('直播已开启');
player.src('http://175.27.168.120:6012/live/2.flv');
player.play();
} else {
createMessage.error('开始直播失败');
}
@ -133,6 +135,7 @@
},
],
licenseUrl: 'http://175.27.168.120:6012/live/2.flv', // license license licenseUrl
autoplay: true, //
});
}, 1000);
});

@ -1,14 +1,23 @@
<template>
<div class="flight-control" v-if="airportVal" v-drag>
<div class="title">
<div> 飞行控制<i>暂无 </i> </div>
<div>
飞行控制
<!-- {"0":"空闲中","1":"现场调试","2":"远程调试","3":"固件升级中","4":"作业中","5":"待标定"} -->
<i v-if="airportVal.mode_code == 0"> </i>
<i v-else-if="airportVal.mode_code == 1">现场调试 </i>
<i v-else-if="airportVal.mode_code == 2">远程调试 </i>
<i v-else-if="airportVal.mode_code == 3">固件升级中 </i>
<i v-else-if="airportVal.mode_code == 4">作业中 </i>
<i v-else-if="airportVal.mode_code == 5">待标定 </i>
</div>
<div @click="emits('changeFlightControl')">
<CloseOutlined />
</div>
</div>
<div class="content">
<div class="content-button">
<a-button @click="emits('clickTakeOff')"></a-button>
<a-button @click="takeOff"></a-button>
<a-button @click="emits('clickFlyTo')"></a-button>
<!-- <a-button>智能环绕</a-button> -->
<a-button @click="returnVoyage"></a-button>
@ -37,7 +46,7 @@
</template>
<script setup lang="ts">
import { onMounted, ref, watch, reactive, onUnmounted } from 'vue';
import { getClient, createConnection } from '@/utils/mqtt';
import { getClient, createSeizeConnection, destroySeizeConnection } from '@/utils/mqtt';
import { CloseOutlined } from '@ant-design/icons-vue';
import { vDrag } from '@/utils/drag';
import { drcDownTopicReize, eventsTopicSubscribeReize } from '@/utils/debugging/events';
@ -49,13 +58,23 @@
} from '@/utils/debugging/remote';
import { buildGUID } from '@/utils/uuid';
import { useMessage } from '@/hooks/web/useMessage';
import {
getRedisUser,
addOrUpdateRedisUser,
getLockedClients,
} from '@/api/workmanagement/airportMaintenance';
import { useUserStore } from '@/store/modules/user';
import { timestampToFormattedDate } from '@/utils/index';
const userStore = useUserStore();
const userInfo = userStore.getUserInfo;
const redisUser = ref({});
const { createMessage } = useMessage();
const emits = defineEmits(['changeFlightControl', 'clickTakeOff', 'clickFlyTo']);
const props = defineProps({
airportAllVal: Object,
});
console.log(props);
//
const flightGrab = ref(false);
//
const modeEnter = ref(false);
const airportVal: any = ref({
mode_code: 0,
wind_speed: 0,
@ -77,39 +96,66 @@
yaw: 1024,
gimbal_pitch: 1024,
});
watch(
() => props.airportAllVal,
(val) => {
console.log(val);
airportVal.value = val.data;
},
);
//redis
const changeRedisUser = (val: boolean) => {
const querys = redisUser.value;
querys.isLock = val;
querys.connectTime = timestampToFormattedDate(new Date().getTime());
addOrUpdateRedisUser(querys);
};
const isLocked = ref(false);
// redis
const lockedClient = () => {
getLockedClients().then((res) => {
console.log(res);
if (res.length > 0) {
res.forEach((item, index) => {
if (item.userId != userInfo.id) {
isLocked.value = true;
}
});
}
});
};
//
const takeOff = () => {
if (isLocked.value) {
createMessage.success('当前有用户正在操作,请稍后再试');
return;
}
emits('clickTakeOff');
changeRedisUser(true);
};
//
const obtain = () => {
if (!getClient()) {
createConnection();
// if (!getClient()) {
// createConnection();
// }
if (isLocked.value) {
createMessage.success('当前有用户正在操作,请稍后再试');
return;
}
setTimeout(() => {
//
servicesTopic({
bid: buildGUID(),
method: 'flight_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {},
});
//
servicesTopic({
bid: buildGUID(),
method: 'payload_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
payload_index: '99-0-0',
},
});
services_replyTopic();
}, 1000);
changeRedisUser(true);
//
servicesTopic({
bid: buildGUID(),
method: 'flight_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {},
});
//
servicesTopic({
bid: buildGUID(),
method: 'payload_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
payload_index: '99-0-0',
},
});
services_replyTopic();
};
//
const returnVoyage = () => {
@ -125,11 +171,19 @@
};
const seq = ref(1);
const changeDRC = (type, value) => {
if (!modeEnter.value) {
createMessage.warning('请先进入指令飞行控制');
return;
}
seq.value = seq.value + 1;
if (value == 'up') {
data[type] = data[type] + 20;
if (data[type] < 1684) {
data[type] = data[type] + 20;
}
} else {
data[type] = data[type] - 20;
if (data[type] > 364) {
data[type] = data[type] - 20;
}
}
const querys = {
seq: seq.value,
@ -144,6 +198,11 @@
};
const drcSeq = ref(1);
const enterDRC = () => {
if (!flightGrab.value) {
createMessage.warning('请先获取飞行控制权');
return;
}
createSeizeConnection();
//
const querys = {
bid: buildGUID(),
@ -200,20 +259,44 @@
servicesTopic(querys);
};
onMounted(() => {
// mqtt
getRedisUser(userInfo.id).then((res) => {
console.log(res);
if (res) {
redisUser.value = res;
}
});
lockedClient();
// //
getClient().on('message', (topic, message) => {
const rs = JSON.parse(message);
if (rs.data.mode_code || rs.data.mode_code == 0) {
airportVal.value = rs.data;
}
if (rs.method == 'flight_authority_grab') {
console.log(rs);
if (rs.data.result == 0) {
flightGrab.value = true;
createMessage.success('飞行控制权抢夺成功');
} else {
flightGrab.value = false;
createMessage.error('飞行控制权抢夺失败,状态码' + rs.data.result);
}
}
if (rs.method == 'drc_mode_enter') {
console.log(rs);
if (rs.data.result == 0) {
modeEnter.value = true;
createMessage.success('进入指令飞行控制模式成功');
} else {
modeEnter.value = false;
createMessage.error('进入指令飞行控制模式失败,状态码' + rs.data.result);
}
}
if (rs.method == 'drc_mode_exit') {
console.log(rs);
if (rs.data.result == 0) {
modeEnter.value = false;
createMessage.success('退出指令飞行控制模式成功');
} else {
createMessage.error('退出指令飞行控制模式失败,状态码' + rs.data.result);
@ -248,6 +331,8 @@
});
onUnmounted(() => {
window.clearInterval(timer);
destroySeizeConnection();
changeRedisUser(false);
});
</script>
<style lang="less" scoped>

@ -7,19 +7,21 @@
</div>
</div>
<div class="content">
<div class="content-item">
<!-- <div class="content-item">
<span>相机控制权</span>
<a-button @click="obtain"></a-button>
</div>
</div> -->
<!-- <div class="content-item">
<span>切换相机模式</span>
<a-button>抢夺负载控制</a-button>
</div> -->
<div class="content-item">
<!-- <div class="content-item">
<span>拍照</span>
<a-button @click="singleShot"></a-button>
</div>
</div> -->
<div class="content-button">
<a-button @click="obtain"></a-button>
<a-button @click="singleShot"></a-button>
<a-button @click="enterDRC"></a-button>
<a-button @click="exitDRC">退</a-button>
</div>
@ -47,20 +49,38 @@
</template>
<script setup lang="ts">
import { onMounted, ref, watch, reactive, onUnmounted } from 'vue';
import { getClient, createConnection } from '@/utils/mqtt';
import { getClient, createSeizeConnection, destroySeizeConnection } from '@/utils/mqtt';
import { CloseOutlined } from '@ant-design/icons-vue';
import { vDrag } from '@/utils/drag';
import { buildGUID } from '@/utils/uuid';
import { servicesTopic, services_replyTopic } from '@/utils/debugging/remote';
import { drcDownTopicReize, eventsTopicSubscribeReize } from '@/utils/debugging/events';
import {
drcDownTopicReize,
eventsTopicSubscribeReize,
eventsTopicReize,
} from '@/utils/debugging/events';
import { useMessage } from '@/hooks/web/useMessage';
import {
getRedisUser,
addOrUpdateRedisUser,
getLockedClients,
} from '@/api/workmanagement/airportMaintenance';
import { useUserStore } from '@/store/modules/user';
import { timestampToFormattedDate } from '@/utils/index';
const userStore = useUserStore();
const userInfo = userStore.getUserInfo;
const redisUser = ref({});
const { createMessage } = useMessage();
const emits = defineEmits(['changeLoadControl']);
const props = defineProps({
msgData: Object,
});
console.log(props);
//
const flightGrab = ref(false);
//
const modeEnter = ref(false);
const drcVal = reactive({
roll: 1024,
pitch: 1024,
@ -90,35 +110,62 @@
}
},
);
//redis
const changeRedisUser = (val: boolean) => {
const querys = redisUser.value;
querys.isLock = val;
querys.connectTime = timestampToFormattedDate(new Date().getTime());
addOrUpdateRedisUser(querys);
};
const isLocked = ref(false);
// redis
const lockedClient = () => {
getLockedClients().then((res) => {
console.log(res);
if (res.length > 0) {
res.forEach((item, index) => {
if (item.userId != userInfo.id) {
isLocked.value = true;
}
});
}
});
};
const obtain = () => {
if (!getClient()) {
createConnection();
// if (!getClient()) {
// createConnection();
// }
if (isLocked.value) {
createMessage.success('当前有用户正在操作,请稍后再试');
return;
}
setTimeout(() => {
//
servicesTopic({
bid: buildGUID(),
method: 'flight_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {},
});
//
servicesTopic({
bid: buildGUID(),
method: 'payload_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
payload_index: '99-0-0',
},
});
services_replyTopic();
}, 1000);
changeRedisUser(true);
//
servicesTopic({
bid: buildGUID(),
method: 'flight_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {},
});
//
servicesTopic({
bid: buildGUID(),
method: 'payload_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
payload_index: '99-0-0',
},
});
services_replyTopic();
};
//
const singleShot = () => {
if (!flightGrab.value) {
createMessage.warning('请先获取相机控制权');
return;
}
//
eventsTopicReize({
bid: buildGUID(),
@ -132,6 +179,11 @@
};
const drcSeq = ref(1);
const enterDRC = () => {
if (!flightGrab.value) {
createMessage.warning('请先获取相机控制权');
return;
}
createSeizeConnection();
//
const querys = {
bid: buildGUID(),
@ -185,26 +237,70 @@
};
servicesTopic(querys);
};
const seq = ref(1);
//
const changeDrc = (type, val) => {
if (!modeEnter.value) {
createMessage.warning('请先进入指令飞行控制');
return;
}
seq.value = seq.value + 1;
if (val == 'up') {
drcVal[type] = drcVal[type] + 20;
if (drcVal[type] < 1684) {
drcVal[type] = drcVal[type] + 20;
}
} else {
drcVal[type] = drcVal[type] - 20;
if (drcVal[type] > 364) {
drcVal[type] = drcVal[type] - 20;
}
}
const querys = {
seq: 1,
seq: seq.value,
method: 'stick_control',
data: drcVal,
};
drcDownTopicReize(querys);
};
onMounted(() => {
// mqtt
getRedisUser(userInfo.id).then((res) => {
console.log(res);
if (res) {
redisUser.value = res;
}
});
lockedClient();
// //
getClient().on('message', (topic, message) => {
const rs = JSON.parse(message);
if (rs.method == 'takeoff_to_point') {
if (rs.method == 'flight_authority_grab') {
console.log(rs);
if (rs.data.result == 0) {
flightGrab.value = true;
createMessage.success('飞行控制权抢夺成功');
} else {
flightGrab.value = false;
createMessage.error('飞行控制权抢夺失败,状态码' + rs.data.result);
}
}
if (rs.method == 'drc_mode_enter') {
console.log(rs);
if (rs.data.result == 0) {
modeEnter.value = true;
createMessage.success('进入指令飞行控制模式成功');
} else {
modeEnter.value = false;
createMessage.error('进入指令飞行控制模式失败,状态码' + rs.data.result);
}
}
if (rs.method == 'drc_mode_exit') {
console.log(rs);
if (rs.data.result == 0) {
modeEnter.value = false;
createMessage.success('退出指令飞行控制模式成功');
} else {
createMessage.error('退出指令飞行控制模式失败,状态码' + rs.data.result);
}
}
if (rs.method === 'drc_status_notify') {
console.log(rs);
@ -220,6 +316,8 @@
});
onUnmounted(() => {
window.clearInterval(timer);
destroySeizeConnection();
changeRedisUser(false);
});
</script>
<style lang="less" scoped>
@ -287,6 +385,7 @@
}
.direction-controller {
position: relative;
margin-top: 20px;
img {
margin-left: 60px;
width: 200px;

@ -12,7 +12,7 @@
<div class="content">
<div class="content-title">
{{ time }}
<span>临近或已接近夜晚</span>
<!-- <span>临近或已接近夜晚</span> -->
</div>
<div class="content-item">
<div class="item-div">

Loading…
Cancel
Save