wo-user-websocket-uniapp/unisocket.js
2023-03-16 08:08:56 +08:00

87 lines
2.8 KiB
JavaScript

const my = {
socket: undefined,
reconnecting: undefined,
listeners: {},
}
export default {
initSocket (url, reconnect = false) {
if (!my.socket || (my.socket.readyState !== my.socket.OPEN && typeof url === 'string')) {
console.log(`WebSocket is connecting to ${url}...`)
my.socket = uni.connectSocket({
url: url.replace(/^http/, 'ws'),
complete: () => {},
})
my.socket.onOpen((res) => {
console.log('WebSocket onOpen: ', res)
clearInterval(my.reconnecting)
delete my.reconnecting
if (reconnect && uni.getStorageSync('_passtoken')) {
console.log('Reporting owner for reconnecting socket')
my.socket.send({ data: JSON.stringify({ skevent: 'SOCKET_OWNER', _passtoken: uni.getStorageSync('_passtoken') }) })
}
})
my.socket.onClose((res) => {
console.log('Websocket onClose: ', res)
if (!my.reconnecting)
my.reconnecting = setInterval(() => {
console.log(new Date().toJSON(), 'WebSocket reconnecting...')
this.initSocket(url, true)
}, 5000) // 每5秒尝试重连
})
my.socket.onError((err) => {
console.log('Websocket onError: ', err)
})
my.socket.onMessage(({ data }) => {
// 在这里统一分发消息(用户端通常不需要返回结果给服务器,因此不用 rpc 模式,而用 event 模式。
try {
let { skevent, ...apiWhat } = JSON.parse(data)
console.log('WebSocket onMessage for skevent: ', skevent)
let listeners = my.listeners[skevent] || []
for (let listener of listeners) {
listener(apiWhat)
}
} catch (exception) {
console.log(new Date().toJSON(), 'unknown message', data)
return
}
})
}
return this
},
closeSocket () {
if (my.socket) my.socket.close()
setTimeout(() => {
clearInterval(my.reconnecting)
delete my.reconnecting
}, 2000)
},
initListener (skevent, listener) {
// 当该 skevent 尚不具有任何 listener 时,添加本 listener
my.listeners[skevent]?.length > 0 || this.addListener(skevent, listener)
return this
},
addListener (skevent, listener) {
if (Array.isArray(my.listeners[skevent]) && typeof listener === 'function') {
my.listeners[skevent].push(listener)
} else {
my.listeners[skevent] = [listener]
}
return this
},
countListener (skevent) {
if (Array.isArray(my.listeners[skevent])) {
return my.listeners[skevent].length
}
return 0
},
sendObject (dataObj) {
if (my.socket && my.socket.readyState === my.socket.OPEN) {
my.socket.send({
data: typeof dataObj !== 'string' ? JSON.stringify(dataObj) : dataObj,
})
}
},
}