forked from drone/command-center-dashboard

罗广辉
2025-04-21 2800fa4f32f3900509cb4d6eefaf2bfaf54efdd7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import {
  DRC_METHOD,
} from '@/const/drc.js'
import EventBus from '@/event-bus'
import { useStore } from 'vuex'
 
 
 
export function useMqtt (mqttState,deviceTopicInfo) {
  let cacheSubscribeArr= []
 
 
  function publishMqtt (topic, body, ots) {
    mqttState?.publishMqtt(topic, JSON.stringify(body), ots)
  }
 
  function subscribeMqtt (topic, handleMessageMqtt) {
    mqttState?.subscribeMqtt(topic)
    const handler = handleMessageMqtt || onMessageMqtt
    mqttState?.on('onMessageMqtt', handler)
    cacheSubscribeArr.push({
      topic,
      callback: handler,
    })
  }
 
  function onMessageMqtt (message) {
    if (cacheSubscribeArr.findIndex(item => item.topic === message?.topic) !== -1) {
      const payloadStr = new TextDecoder('utf-8').decode(message?.payload)
      const payloadObj = JSON.parse(payloadStr)
      switch (payloadObj?.method) {
        case DRC_METHOD.HEART_BEAT:
          break
        case DRC_METHOD.DELAY_TIME_INFO_PUSH:
        case DRC_METHOD.HSI_INFO_PUSH:
        case DRC_METHOD.OSD_INFO_PUSH:
        case DRC_METHOD.DRONE_CONTROL:
        case DRC_METHOD.DRONE_EMERGENCY_STOP:
          EventBus.emit('droneControlMqttInfo', payloadObj)
          break
        default:
          break
      }
    }
  }
 
  function unsubscribeDrc () {
    // 销毁已订阅事件
    cacheSubscribeArr.forEach(item => {
      mqttState?.off('onMessageMqtt', item.callback)
      mqttState?.unsubscribeMqtt(item.topic)
    })
    cacheSubscribeArr = []
  }
 
  // 心跳
  const heartBeatSeq = ref(0)
  const state = reactive({
    heartState: new Map(),
  })
 
  // 监听云控控制权
  watch(() => deviceTopicInfo, (val, oldVal) => {
    if (val.subTopic !== '') {
      // 1.订阅topic
      subscribeMqtt(deviceTopicInfo.subTopic)
      // 2.发心跳
      publishDrcPing(deviceTopicInfo.sn)
    } else {
      console.log('清除pingInterval')
      clearInterval(state.heartState.get(deviceTopicInfo.sn)?.pingInterval)
      state.heartState.delete(deviceTopicInfo.sn)
      heartBeatSeq.value = 0
    }
  }, { immediate: true, deep: true })
 
  function publishDrcPing (sn) {
    const body = {
      method: DRC_METHOD.HEART_BEAT,
      data: {
        ts: new Date().getTime(),
        seq: heartBeatSeq.value,
      },
    }
    const pingInterval = setInterval(() => {
      if (!mqttState) return
      heartBeatSeq.value += 1
      body.data.ts = new Date().getTime()
      body.data.seq = heartBeatSeq.value
      publishMqtt(deviceTopicInfo.pubTopic, body, { qos: 0 })
    }, 1000)
    state.heartState.set(sn, {
      pingInterval,
    })
  }
 
  onUnmounted(() => {
    unsubscribeDrc()
    heartBeatSeq.value = 0
  })
 
  return {
    mqttState,
    publishMqtt,
    subscribeMqtt,
  }
}