/**
* @desc websocket 工具类
* @param url 连接url
* @param callback 接收消息回调函数
* @param config 配置项:
* reconnectCount: 3 (重连次数,默认3次)
* reconnentInterval: 3000 (重连间隔,默认3秒)
* resendMessageCount: 3 (重发消息次数,默认3次)
* resendMessageInterval: 1000 (重发消息间隔,默认1秒)
* heartBeatInterval: 5000 (心跳间隔时长,默认5秒)
* onOpen: Function (连接成功回调)
* onClose: Function (连接关闭回调)
* onError: Function (连接错误回调)
* @auth Roffer
* @date 2022/5/13 15:01
*
*/
export default class Socket {
constructor(url, callback, config = {}) {
this.option = {
//重连次数,默认3次
reconnectCount: 3,
//重连间隔,默认3秒
reconnentInterval: 3000,
//重发消息次数,默认3次
resendMessageCount: 3,
//重发消息间隔,默认1秒
resendMessageInterval: 1000,
//心跳间隔时长,默认5秒
heartBeatInterval: 5000,
//连接成功回调
onOpen(){},
//连接关闭回调
onClose(){},
//连接错误回调
onError(){},
...config
}
//链接地址(不带ws://)
this.url = url
//回调函数
this.callback = callback || ((data) => {
})
//实例
this.instance = null
//是否连接中
this.isConnecting = false
//心跳定时器对象,断开时清除
this.__heartBeatIntervalInstance = null
this.__reconnectCount = this.option.reconnectCount
this.__resendMessageCount = this.option.resendMessageCount
this.__heartBeatInterval = this.option.heartBeatInterval
this.__reconnentInterval = this.option.reconnentInterval
this.__resendMessageInterval = this.option.resendMessageInterval
//是否已连接
this.isConnected = false
this.connect()
}
/** 初始化连接 **/
connect() {
this.__reconnectCount--
this.isConnecting = true
let instance = new WebSocket(this.url)
instance.onmessage = (e) => {
this.callback instanceof Function && this.callback(e.data)
}
instance.onclose = (e) => {
console.log('连接关闭!')
this.isConnected = false
this.__reset()
this.option.onClose(e)
}
instance.onopen = (e) => {
console.log('连接成功!')
this.isConnected = true
this.__reset()
//连接成功,执行心跳连接,保持连接通畅
this.__heartBeat()
this.option.onOpen(e)
}
instance.onerror = (e) => {
console.log('连接失败!')
this.isConnecting = false
this.isConnected = false
setTimeout(() => {
this.__reconnect()
}, this.__reconnentInterval)
this.option.onError(e)
}
this.instance = instance
}
/** 发送消息到服务端 **/
sendMessage(data) {
return new Promise((resolve, reject) => {
const send = () => {
if (this.instance.readyState == this.instance.OPEN) {
let params = typeof data === 'string' ? data : JSON.stringify(data)
this.instance.send(params)
//发送成功,将重发次数重置
this.__resendMessageCount = this.option.resendMessageCount
resolve({code: 200, message: '发送成功'})
} else {
if (this.__resendMessageCount === 0) {
this.__resendMessageCount = this.option.resendMessageCount
//如果3次都没有发送成功,说明连接断开,进行重连
this.__reconnect()
reject({code: 500, message: '连接失败'})
} else {
setTimeout(() => {
send()
}, this.__resendMessageInterval)
this.__resendMessageCount--
}
}
}
send()
})
}
/** 断开连接 **/
close() {
this.instance && this.instance.close()
}
/** 重置参数 */
__reset(){
this.__reconnectCount = this.option.reconnectCount
this.__resendMessageCount = this.option.resendMessageCount
this.isConnecting = false
//清除心跳定时器
this.__heartBeatIntervalInstance && clearInterval(this.__heartBeatIntervalInstance)
}
/** 重连 */
__reconnect() {
if (!this.isConnecting && this.instance.readyState !== this.instance.OPEN && this.__reconnectCount > 0) {
this.connect()
}
}
/** 心跳连接 */
__heartBeat() {
this.__heartBeatIntervalInstance && clearInterval(this.__heartBeatIntervalInstance)
this.__heartBeatIntervalInstance = setInterval(() => {
this.sendMessage({isHeartBeat: true})
}, this.__heartBeatInterval)
}
}
JS websocket工具类
于 2023-11-15 11:22:04 首次发布