addEventListener('message', (e) => { const { data } = e let datas = JSON.parse(data) // console.log(datas) if (!WebSocket) message.error('你的浏览器不支持WebSocket') const baseUrl = import.meta.env.VITE_APP_API_BASE_URL.match(/^http(s)?:\/\/([^\/]*).*/)[2] // if (process.env.NODE_ENV !== 'development') { // data.wsAirport = WebSocketService.createConnection(`wss://${baseUrl}/airport/socket/webSocket/${url}`) // } else { // data.wsAirport = WebSocketService.createConnection(`wss://${baseUrl}/airport/socket/webSocket/${url}`) // } if (datas.id && datas.code) { // return //开始发送sockets请求 //当前机场socket let wsAirport = new WebSocketService() wsAirport.createConnection(`wss://${baseUrl}/airport/socket/webSocket/0:0:${datas.code}`) //日志socket // let wsLog = new WebSocketService().createConnection( // `wss://${baseUrl}/airport/socket/logSocket/${datas.id}`, // ) wsAirport.onmessage = (event) => { if (!WebSocketService.isJsonString(event.data)) return // const wsData = JSON.parse(event.data) // console.log(wsData) //发送给主线程 return postMessage(event.data) // const currentDroneInfo data.currentDroneInfo || null let droneYaw = null // if(data.currentDroneInfo){ // // 定义起点和终点坐标 // const startPoint = turf.point([ data.currentDroneInfo.longitude, data.currentDroneInfo.latitude]) // 扬子大队 // const endPoint = turf.point([wsData.lon, wsData.lat]) // 六合大队 // // 计算两点之间的方位角(偏航角) // droneYaw = turf.bearing(startPoint, endPoint) // } // 无人机 // data.wsAirportInfo = wsData ? { ...wsData, droneYaw } : {} // 天气数据 // data.weather = wsData.weather || {} } // 日志消息 // wsLog.onmessage = (event) => { // if (!WebSocketService.isJsonString(event.data)) return // const wsData = JSON.parse(event.data) // console.log(wsData) // } } // return postMessage('111111111111111') // if (airLineBuffer) { //向主线程发送数据 // return postMessage(JSON.stringify(airLineBuffer)) // } }) const socketCount = 30 class WebSocketService { constructor() {} initConnection(conn, that) { // 先清理旧连接 conn.clearConnection() if (conn.closed) return conn.socket = new WebSocket(conn.url) conn.socket.onopen = () => { // console.log(`Connection opened: ${conn.url}`) function sendFn() { // console.log(that) conn.intervalId = setTimeout(() => { // if (conn.closed) return // 超过 30 秒没收到心跳就重连 (最多重连 30 次) if (Date.now() - conn.lastHeartbeat > 30000 && conn.againTimes < socketCount) { let againTimes = conn.againTimes++ console.log('ws心跳超时,尝试重连222', againTimes, conn.againTimes) that.initConnection(conn) //超过30次了 clearTimeout(conn.intervalId) return } else { conn.socket.send('ping') sendFn() } }, 10000) } sendFn() } conn.socket.onmessage = (event) => { conn.lastHeartbeat = Date.now() let msg try { msg = JSON.parse(event.data) } catch { // 非 JSON 消息直接转给业务 return conn.onmessage(event) } if (msg.type === 'pong') { console.log('收到心跳 pong') } else { conn.onmessage(event) } } conn.socket.onerror = (err) => { console.error(`Error in connection ${conn.url}:`, err) conn.onerror(err) } conn.socket.onclose = () => { console.log(`Connection closed: ${conn.url}`) conn.onclose() if (!conn.closed) { let againTimes = conn.againTimes++ console.log('ws心跳超时,尝试重连1111', againTimes, conn.againTimes) // 超过 30 秒没收到心跳就重连 (最多重连 30 次) if (againTimes > socketCount) { return } conn.intervalId = setTimeout(() => { // 自动重连 this.initConnection(conn) }, 10000) } else { clearTimeout(conn.intervalId) } } } createConnection(url) { const conn = { url, socket: null, lastHeartbeat: Date.now(), intervalId: null, closed: false, againTimes: 0, // 重连次数 onopen: () => {}, onmessage: () => {}, onerror: () => {}, onclose: () => {}, sendMessage(msg) { if (this.closed) { console.error('WebSocket 已关闭') return } if (this.socket && this.socket.readyState === WebSocket.OPEN) { this.socket.send(msg) } else { console.error('WebSocket 未打开') } }, clearConnection() { if (this.socket) this.socket.close() if (this.intervalId) clearTimeout(this.intervalId) }, close() { console.log(`Connection 人工关闭`) this.closed = true this.clearConnection() }, } this.initConnection(conn, this) return conn } static isJsonString(str) { try { JSON.parse(str) } catch (e) { return false } return true } }