glhcp/uniapp/utils/socket.js

138 lines
2.8 KiB
JavaScript

//
import {
paramsToStr
} from './tools'
class Socket {
constructor(url, data) {
this.connected = false
this.error = false
this.url = `${url}${paramsToStr(data)}`
this.socketTask = {}
this.reconnectLock = true
this.reconnectTimeout = null
this.reconnectNums = 0
// 心跳
this.timeout = 10000
this.clientTimeout = null
this.serverTimeout = null
}
// 允许的订阅
events = {
connect: null,
close: null,
message: null,
error: null,
open: null
}
// 添加订阅
addEvent(type, callback) {
this.events[type] = callback
}
// 触发订阅
dispatch(type, data) {
const fun = this.events[type]
fun && fun(data)
}
connect() {
// 已经连接则无需重复连接
if (this.connected) return
this.dispatch('connect')
this.socketTask = uni.connectSocket({
url: this.url,
complete: () => {}
})
this.socketTask.onOpen(this.onOpen.bind(this))
this.socketTask.onError(this.onError.bind(this));
this.socketTask.onMessage(this.onMessage.bind(this))
this.socketTask.onClose(this.onClose.bind(this));
}
close() {
this.reconnectLock = false
clearTimeout(this.clientTimeout)
clearTimeout(this.serverTimeout)
this.socketTask.close && this.socketTask.close()
}
reconnect() {
if (!this.reconnectLock) {
return
}
// 重连次数过多,断开不重连
if (this.reconnectNums >= 5) {
return
}
this.reconnectNums++
this.reconnectLock = false
// 延迟重连请求过多
clearTimeout(this.reconnectTimeout)
this.reconnectTimeout = setTimeout(() => {
this.connect()
this.reconnectLock = true
}, 4000)
}
start() {
clearTimeout(this.clientTimeout)
clearTimeout(this.serverTimeout)
this.clientTimeout = setTimeout(() => {
this.send({
event: 'ping'
})
this.serverTimeout = setTimeout(() => {
this.socketTask.close()
}, this.timeout)
}, this.timeout)
}
reset() {
this.reconnectNums = 0
this.start()
}
send(data) {
// 如果socket已连接则发送消息
if (!this.connected) {
return
}
let datas = JSON.stringify(data)
// console.log('发送信息:' + datas)
this.socketTask.send({
data: datas,
})
}
onOpen() {
this.connected = true
// 开启心跳
this.start()
// console.log('连接成功')
this.dispatch('open')
}
onError(res) {
this.error = true
this.connected = false
this.dispatch('error')
// console.log('连接错误', res)
}
onMessage({data}) {
this.dispatch('message', JSON.parse(data))
// console.log('收到信息:', data)
// 重置心跳
this.reset()
}
onClose(res) {
this.dispatch('close')
// console.log('连接已关闭', res)
this.connected = false
this.reconnect()
}
}
export default Socket