add heartbeating

This commit is contained in:
Luk 2024-02-04 11:29:25 +08:00
parent ebbf67fba9
commit 43269c82e6

View File

@ -1,49 +1,60 @@
const my = { const my = {
socket: undefined, socket: undefined,
reconnecting: undefined, reconnecting: undefined,
heartbeating: undefined,
listeners: {}, listeners: {},
} }
export default { export default {
initSocket (url, reconnect = false) { initSocket (url, relogin = false) {
if (!my.socket || (my.socket.readyState !== my.socket.OPEN && typeof url === 'string')) { if (!my.socket || (my.socket.readyState !== my.socket.OPEN && typeof url === 'string')) {
console.log(`WebSocket is connecting to ${url}...`) console.log(new Date().toJSON(), `WebSocket is connecting to ${url}...`)
my.socket = uni.connectSocket({ my.socket = uni.connectSocket({
url: url.replace(/^http/, 'ws'), url: url.replace(/^http/, 'ws'),
complete: () => { }, complete: () => { },
}) })
my.socket.onOpen((res) => { my.socket.onOpen((res) => {
console.log('WebSocket onOpen: ', res) console.log(new Date().toJSON(), 'WebSocket onOpen: ', res)
clearInterval(my.reconnecting) clearInterval(my.reconnecting)
delete my.reconnecting delete my.reconnecting
if (reconnect && uni.getStorageSync('_passtoken')) { // 前端断线重连时,并不会自动提供 _passtoken。在前端的initSocket时应当把_passtoken送过来而后台则对_passtoken做验证后再加socketPool。
console.log('Reporting owner for reconnecting socket') if (relogin && uni.getStorageSync('_passtoken')) {
console.log(new Date().toJSON(), 'Reporting owner for reconnecting socket')
my.socket.send({ data: JSON.stringify({ skevent: 'SOCKET_OWNER_RECONNECT', _passtoken: uni.getStorageSync('_passtoken') }) }) my.socket.send({ data: JSON.stringify({ skevent: 'SOCKET_OWNER_RECONNECT', _passtoken: uni.getStorageSync('_passtoken') }) })
} }
my.heartbeating = setInterval(() => {
if (my.socket && my.socket.readyState === my.socket.OPEN) {
my.socket.send({ data: JSON.stringify({ skevent: 'PING' }) })
} else {
clearInterval(my.heartbeating)
delete my.heartbeating
}
}, 20000) // 定期发送心跳,避免被关闭
}) })
my.socket.onClose((res) => { my.socket.onClose((res) => {
console.log('Websocket onClose: ', res) console.log(new Date().toJSON(), 'Websocket onClose: ', res)
if (!my.reconnecting) if (!my.reconnecting)
my.reconnecting = setInterval(() => { my.reconnecting = setInterval(() => {
console.log(new Date().toJSON(), 'WebSocket reconnecting...') console.log(new Date().toJSON(), 'Websocket reconnecting...')
this.initSocket(url, true) this.initSocket(url, true)
}, 5000) // 每5秒尝试重连 }, 5000) // 每5秒尝试重连
}) })
my.socket.onError((err) => { my.socket.onError((err) => {
console.log('Websocket onError: ', err) console.log(new Date().toJSON(), 'Websocket onError: ', err)
}) })
my.socket.onMessage(({ data }) => { my.socket.onMessage(({ data }) => {
// 在这里统一分发消息(用户端通常不需要返回结果给服务器,因此不用 rpc 模式,而用 event 模式。 // 在这里统一分发消息(用户端通常不需要返回结果给服务器,因此不用 rpc 模式,而用 event 模式。
try { try {
let { skevent, ...apiWhat } = JSON.parse(data) let { skevent, ...apiWhat } = JSON.parse(data)
console.log('WebSocket onMessage for skevent: ', skevent) console.log(new Date().toJSON(), 'Websocket onMessage for skevent: ', skevent)
let listeners = my.listeners[skevent] || [] let listeners = my.listeners[skevent] || []
for (let listener of listeners) { for (let listener of listeners) {
listener(apiWhat) listener(apiWhat)
} }
} catch (exception) { } catch (exception) {
console.log(new Date().toJSON(), 'unknown message', data, exception) console.log(new Date().toJSON(), 'Websocket onMessage unknown', data, exception)
return return
} }
}) })