{"version":3,"file":"useWebSocket.js","sources":["../../../../../src/sheep/hooks/useWebSocket.js"],"sourcesContent":["import { onBeforeUnmount, reactive, ref } from 'vue'\r\nimport { baseUrl, websocketPath } from '@/sheep/config'\r\nimport { copyValueToTarget } from '@/sheep/util'\r\n\r\n/**\r\n * WebSocket 创建 hook\r\n * @param opt 连接配置\r\n * @return {{options: *}}\r\n */\r\nexport function useWebSocket(opt) {\r\n const getAccessToken = () => {\r\n return uni.getStorageSync('token')\r\n }\r\n\r\n const options = reactive({\r\n url: (baseUrl + websocketPath).replace('http', 'ws') + '?token=' + getAccessToken(), // ws 地址\r\n isReconnecting: false, // 正在重新连接\r\n reconnectInterval: 3000, // 重连间隔,单位毫秒\r\n heartBeatInterval: 5000, // 心跳间隔,单位毫秒\r\n pingTimeoutDuration: 1000, // 超过这个时间,后端没有返回pong,则判定后端断线了。\r\n heartBeatTimer: null, // 心跳计时器\r\n destroy: false, // 是否销毁\r\n pingTimeout: null, // 心跳检测定时器\r\n reconnectTimeout: null, // 重连定时器ID的属性\r\n onConnected: () => {}, // 连接成功时触发\r\n onClosed: () => {}, // 连接关闭时触发\r\n onMessage: (data) => {}, // 收到消息\r\n })\r\n const SocketTask = ref(null) // SocketTask 由 uni.connectSocket() 接口创建\r\n\r\n const initEventListeners = () => {\r\n // 监听 WebSocket 连接打开事件\r\n SocketTask.value.onOpen(() => {\r\n console.log('WebSocket 连接成功')\r\n // 连接成功时触发\r\n options.onConnected()\r\n // 开启心跳检查\r\n startHeartBeat()\r\n })\r\n // 监听 WebSocket 接受到服务器的消息事件\r\n SocketTask.value.onMessage((res) => {\r\n try {\r\n if (res.data === 'pong') {\r\n // 收到心跳重置心跳超时检查\r\n resetPingTimeout()\r\n } else {\r\n options.onMessage(JSON.parse(res.data))\r\n }\r\n } catch (error) {\r\n console.error(error)\r\n }\r\n })\r\n // 监听 WebSocket 连接关闭事件\r\n SocketTask.value.onClose((event) => {\r\n // 情况一:实例销毁\r\n if (options.destroy) {\r\n options.onClosed()\r\n } else {\r\n // 情况二:连接失败重连\r\n // 停止心跳检查\r\n stopHeartBeat()\r\n // 重连\r\n reconnect()\r\n }\r\n })\r\n }\r\n\r\n // 发送消息\r\n const sendMessage = (message) => {\r\n if (SocketTask.value && !options.destroy) {\r\n SocketTask.value.send({ data: message })\r\n }\r\n }\r\n // 开始心跳检查\r\n const startHeartBeat = () => {\r\n options.heartBeatTimer = setInterval(() => {\r\n sendMessage('ping')\r\n options.pingTimeout = setTimeout(() => {\r\n // 如果在超时时间内没有收到 pong,则认为连接断开\r\n reconnect()\r\n }, options.pingTimeoutDuration)\r\n }, options.heartBeatInterval)\r\n }\r\n // 停止心跳检查\r\n const stopHeartBeat = () => {\r\n clearInterval(options.heartBeatTimer)\r\n resetPingTimeout()\r\n }\r\n\r\n // WebSocket 重连\r\n const reconnect = () => {\r\n if (options.destroy || !SocketTask.value) {\r\n // 如果WebSocket已被销毁或尚未完全关闭,不进行重连\r\n return\r\n }\r\n\r\n // 重连中\r\n options.isReconnecting = true\r\n\r\n // 清除现有的重连标志,以避免多次重连\r\n if (options.reconnectTimeout) {\r\n clearTimeout(options.reconnectTimeout)\r\n }\r\n\r\n // 设置重连延迟\r\n options.reconnectTimeout = setTimeout(() => {\r\n // 检查组件是否仍在运行和WebSocket是否关闭\r\n if (!options.destroy) {\r\n // 重置重连标志\r\n options.isReconnecting = false\r\n // 初始化新的WebSocket连接\r\n initSocket()\r\n }\r\n }, options.reconnectInterval)\r\n }\r\n\r\n const resetPingTimeout = () => {\r\n if (options.pingTimeout) {\r\n clearTimeout(options.pingTimeout)\r\n options.pingTimeout = null // 清除超时ID\r\n }\r\n }\r\n\r\n const close = () => {\r\n options.destroy = true\r\n stopHeartBeat()\r\n if (options.reconnectTimeout) {\r\n clearTimeout(options.reconnectTimeout)\r\n }\r\n if (SocketTask.value) {\r\n SocketTask.value.close()\r\n SocketTask.value = null\r\n }\r\n }\r\n\r\n const initSocket = () => {\r\n options.destroy = false\r\n copyValueToTarget(options, opt)\r\n SocketTask.value = uni.connectSocket({\r\n url: options.url,\r\n complete: () => {},\r\n success: () => {},\r\n })\r\n initEventListeners()\r\n }\r\n\r\n initSocket()\r\n\r\n onBeforeUnmount(() => {\r\n close()\r\n })\r\n return { options }\r\n}\r\n"],"names":["uni","reactive","baseUrl","websocketPath","ref","copyValueToTarget","onBeforeUnmount"],"mappings":"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"}