websocket封装
class WebSocketClass {
constructor(url,callback, time = 10000) {
this.url = url//连接
this.socket = null // 存储 WebSocket 连接.
this.timeoutObj = null // 心跳定时器
this.serverTimoutObj = null // 服务超时定时关闭
this.lockReconnect = false // 是否真正建立了连接
this.timeoutnum = null // 重新连接的定时器, 没连接上会一直重连,设置延迟避免请求过多
this.retryTimeout = time
this.callback = callback
try {
return this.initWebSocket()
} catch (error) {
console.log(error)
//重连
this.reconnect()
}
}
//初始化
initWebSocket() {
if (!this.socket) {
this.socket = new WebSocket(this.url)
this.socket.onopen = () => {
console.log('socket连接成功')
this.start()
}
this.socket.onclose = () => {
console.log('socket已经关闭')
}
this.socket.onerror = () => {
this.reconnect()
console.log('socket 连接失败')
}
//接收消息
this.socket.onmessage = (res) => {
this.callback(res)
}
} else {
return
}
}
//发送消息
socketOnSend(data) {
this.socket.send(data)
}
//关闭websocket函数
closeWebsocket() {
if (this.socket) {
this.socket.close()
console.log('socket关闭')
}
clearTimeout(this.timeoutObj)
clearTimeout(this.serverTimoutObj)
}
// 开启心跳
start() {
this.timeoutObj && clearTimeout(this.timeoutObj)
this.serverTimoutObj && clearTimeout(this.serverTimoutObj)
this.timeoutObj = setTimeout(() => {
// 这里发送一个心跳,后端收到后返回一个心跳消息
if (this.socket.readyState === 1) {
// 如果连接正常 给后端发送指定消息
this.socket.send('')
console.log('发送消息')
} else {
// 重连
this.reconnect()
}
this.serverTimoutObj = setTimeout(() => {
// 超时关闭连接
this.socket.close()
}, this.retryTimeout);
}, this.retryTimeout);
}
// 重连
reconnect() {
if (this.lockReconnect) {
return
}
this.lockReconnect = true
this.timeoutnum && clearTimeout(this.timeoutnum)
this.timeoutnum = setTimeout(() => {
this.initWebSocket()
this.lockReconnect = false
}, 5000);
}
// 重置心跳
reset() {
// 清除时间
clearTimeout(this.timeoutObj)
clearTimeout(this.serverTimoutObj)
// 重启心跳
this.start()
}
}
export default WebSocketClass
全局引入和调用
//main.js
import WebSocketClass from './socket'//websocket请求
Vue.prototype.$WebSocketClass = WebSocketClass
//页面调用
this.ws = new this.$WebSocketClass(this.socketUrl,(res)=>{
console.log(res)
});