/** * WebSocket 工具函数库 * 整个项目中只会纯在一个WebSocket实例对象(便于兼容) * * 先initWs、再进行registerEvents,最后才能sendWsMsg * * initWs 初始化WebSocket 连接 * registerEvents 注册监听事件 * destroyEvents 销毁已注册的监听事件 * sendWsMsg 发送WebSocket消息(统一发送字符串类型参数,便于兼容) * closeWs 关闭WebSocket连接 * */ import { baseUrl } from '@/config/baseConfig.js' const wsUrl = baseUrl('wsUrl') // 连接地址 let socketTaskAr = [] /** * 检测WebSocket实例是否已经存在 * */ function checkWSInstance () { return !!getApp().globalData.webSocketInstance } function loopCheckWSInstance (cb = null, params) { const _time = setInterval(() => { if (checkWSInstance()) { clearInterval(_time) cb && cb(params) } }, 300) } /** * 初始化WebSocket 连接 * @param {Object} self 页面实例(_vm) * @param {Object} params 附加参数 { send, forever, msg } * send: false/true 表示首次链接完成之后,调用消息发送 * forever: false/true 表示只要调用initWs,且forever为true,就是调用消息发送 * msg: 表示发送的消息内容 * */ export function initWs (self, params = null) { if (checkWSInstance()) { if (params) { if (params.forever) { sendWsMsg(params.msg || '') } } } else { const _appGlobalData = getApp().globalData try { if (_appGlobalData.socketTask) return; const _accessTokenAndMacKey = JSON.parse(uni.getStorageSync('oauthAccessToken')); // 创建连接 _appGlobalData.socketTask = uni.connectSocket({ url: wsUrl + `?token=${_accessTokenAndMacKey.accessToken}`, complete: () => {} }) // 各个事件钩子监听 _appGlobalData.socketTask.onOpen((res) => { console.log('onOpen') if (self) { _appGlobalData.webSocketInstance = _appGlobalData.socketTask socketTaskAr.push(_appGlobalData.socketTask) } if (params) { if (params.send || params.forever) { sendWsMsg(params.msg || '') } } }) _appGlobalData.socketTask.onClose((res) => { console.log('onClose') // 清除已存在的实例对象 _appGlobalData.socketTask = null _appGlobalData.webSocketInstance = null }) _appGlobalData.socketTask.onError((res) => { console.log('onError: 将尝试重新连接webSocket服务!') // 清除已存在的实例对象 if (checkWSInstance()) { _appGlobalData.socketTask = null _appGlobalData.webSocketInstance = null } // 尝试重新连接webSocket服务,次数限定50次 let count = 0 const total = 50 const _timeer = setInterval(() => { count++ if (count <= total) { initWs(self) } else { clearInterval(_timeer) } }, 5 * 1000) }) _appGlobalData.socketTask.onMessage((res) => { // todo 处理注册事件 const _eventsStock = _appGlobalData.registerEventsStock const _len = _eventsStock.length for (let event in _eventsStock) { _eventsStock[event].cb && _eventsStock[event].cb(res) } }) } catch { // 跳转登录页 uni.navigateTo({ url: '/pages/login/index' }); } } } /** * 注册监听事件 * @param {String} eventName 事件名称 * @param {Function} eventFun 处理事件函数(用于回调) * */ export function registerEvents (eventName = 'eventName', eventFun = null) { const _appGlobalData = getApp().globalData const _eventsStock = _appGlobalData.registerEventsStock _appGlobalData.registerEventsStock = { [eventName]: { cb: eventFun }, ..._eventsStock } } /** * 销毁已注册的监听事件 * @param {String} eventName 事件名称 * */ export function destroyEvents (eventName = 'eventName') { const _appGlobalData = getApp().globalData const _eventsStock = _appGlobalData.registerEventsStock delete _eventsStock[eventName] _appGlobalData.registerEventsStock = { ..._eventsStock } } /** * 关闭WebSocket连接 * */ export function closeWs () { socketTaskAr.map(instance => { instance.close() }) socketTaskAr = [] } /** * 发送WebSocket消息(统一发送字符串类型参数,便于兼容) * @param {Object | Array | String} msg 待发送的消息 * */ export function sendWsMsg (msg = '') { if (checkWSInstance()) { const _webSocketInstance = getApp().globalData.webSocketInstance let _msg = '' if (Array.isArray(msg)) { if (mag.length) { _msg = msg.join() } } else if (typeof msg === 'object') { _msg = JSON.stringify(msg) } else { _msg = msg } console.log(_msg) _webSocketInstance.send({ data: _msg }) } else { loopCheckWSInstance(sendWsMsg, msg) } }