xc-app/utils/webSocketUtils.js

182 lines
4.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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)
}
}