1. 在mixins文件夹下写入websocket.js配置文件
思路:初始化时可以传入一个ws接口,也可以手动配置,如果当前支持ws,则开启ws以及其相关的监听:onopen连接成功,onclose连接关闭,onerror连接错误,onmessage返回消息,init时传入一个函数,在获取数据后把数据传入函数,然后调用此函数以方便操作数据
export default {
data() {
return {
socket: '', //WebSocket
}
},
destroyed() {
this.closeWebsocket();
},
methods: {
initWebSocket(fn,url) {
let weburl = url || this.webSocketUrl
if (!window.WebSocket) { return }
if (!this.socket) {
this.socket = new WebSocket(weburl)
this.socketOnOpen()
this.socketOnClose()
this.socketOnError()
this.socketOnMessage(fn)
}
},
/**
* 关闭websocket
*/
closeWebsocket() {
if (this.socket) {
this.socket.close()
}
},
socketOnSend(data) {
this.socket.send(data)
},
socketOnOpen() {
this.socket.onopen = () => {
console.log('连接成功!')
this.socketOnSend('连接成功')
}
},
socketOnClose() {
this.socket.onclose = () => {
console.log('ws已经关闭')
}
},
socketOnError() {
this.socket.onerror = () => {
console.log('ws连接失败')
}
},
socketOnMessage(fn) {
this.socket.onmessage = (e) => {
console.log('返回消息');
fn(JSON.parse(e.data))
}
},
},
}
2.使用:引用,初始化,获得数据
import wsMixin from '@/mixins/websocket.js'
export default {
mixins: [websocketMixin],
created() {
this.webSocketUrl = `接口`
this.initWebSocket(this.callback) //初始化
},
methods:{
callback(data){
console.log(data) //操作返回的数据
}
}
}
有心跳的ws
组件destroyed的时候关闭ws
组件created的时候初始化ws:
- 判断浏览器是否支持,判断当前组件是否有ws实例了
- 开启open,close,error,message监听
- open:连接成功开启心跳
- close:log已经关闭
- error:连接失败启动重连
- message:收到消息,传给回调函数,如果是心跳就重置心跳
- 开启心跳:如果有心跳定时器就清除,定义一个心跳周期定时器,如果readyState是1就发送‘heartbeat’否则就重连,发送心跳后定义一个定时器,如果超时未响应就关闭
- 重置心跳:清除两个定时器,重新开启心跳
- 重连心跳:清除定时器,五秒后初始化ws,定义变量--如果当前没有在重连才会再次初始化
export default {
data() {
return {
socket: '', //WebSocket
lockReconnect: false, // 是否真正建立连接
heartbeatTimeCycle: 20 * 1000, // 定义心跳周期默认为20s
timeoutObj:'', //心跳心跳倒计时
serverTimeoutObj: '', //心跳倒计时
timeoutNum:'',
}
},
destroyed() {
this.closeWebsocket()
},
methods: {
initWebSocket(fn, url) {
let weburl = url || this.webSocketUrl
if (!window.WebSocket) { return }
if (!this.socket) {
this.socket = new WebSocket(weburl)
this.socketOnOpen()
this.socketOnClose()
this.socketOnError()
this.socketOnMessage(fn)
}
},
/**
* 关闭websocket
*/
closeWebsocket() {
if (this.socket) {
this.socket.close()
}
},
socketOnSend(data) {
if (this.socket.readyState == 1)
this.socket.send(data)
},
socketOnOpen() {
this.socket.onopen = () => {
console.log('连接成功!')
this.startHeartbeat();
}
},
socketOnClose() {
this.socket.onclose = () => {
console.log('ws已经关闭')
}
},
socketOnError() {
this.socket.onerror = () => {
console.log('ws连接失败')
this.reconnect()
}
},
socketOnMessage(fn) {
this.socket.onmessage = (e) => {
if (e.data.includes("heartbeat")) {
// 在心跳周期内收到后端消息, 则重置心跳
this.resetHeartbeat();
} else {
// 把后端返回值给回调函数
console.log("收到来自后端的数据");
fn(JSON.parse(e.data))
}
}
},
// 开启心跳
startHeartbeat() {
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
console.log("开启心跳---心跳周期:(毫秒)", this.heartbeatTimeCycle);
this.timeoutObj = setTimeout(() => {
// 如果连接正常
if (this.socket.readyState == 1) {
// 这里发送一个心跳,后端收到后,返回一个心跳消息
this.socket.send('{"heartbeat":"heartbeat"}');
console.log('发送心跳');
} else {
// 否则重连
this.reconnect();
}
this.serverTimeoutObj = setTimeout(() => {
// 超时关闭
console.log("心跳超时未响应---", this.heartbeatTimeCycle);
this.socket.close();
}, this.heartbeatTimeCycle);
}, this.heartbeatTimeCycle);
},
resetHeartbeat() {
//清除时间
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
//重启心跳
this.startHeartbeat();
},
reconnect() {
if (this.lockReconnect) {
return;
}
this.lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
this.timeoutNum && clearTimeout(this.timeoutNum);
this.timeoutNum = setTimeout(() => {
//新连接
console.log('尝试重连',this.socket);
this.initWebSocket(this.global_callback);
this.lockReconnect = false;
}, 5000);
}
},
}