这是我目前正在使用的方式
新建socket.js文件
let Socket = ''
const wsUrl = 'ws://192.168.50.103:5003/experience_api/websocket/'
let store = null;
/**
* 建立websocket连接
*/
export const createSocket = (vuex) => {
vuex && (store = vuex);
Socket = new WebSocket(baseUrl.wsUrl + '?token=' + store.state.token);
//Socket = new WebSocket(wsUrl)
Socket.onopen = onopenWS
Socket.onmessage = onmessageWS
Socket.onerror = onerrorWS
Socket.onclose = oncloseWS
}
/**打开WS之后发送心跳 */
const onopenWS = () => {
console.log("WebSocket:已连接");
heartCheck.reset().start(); //重置,发送心跳
}
/**
* 发生错误的回调
*/
const onerrorWS = () => {
console.log("WebSocket:发生错误");
reconnect(); //重新链接
}
/**WS数据接收统一处理 */
const onmessageWS = e => {
store.commit('setMessage', e.data); //存入vuex中
heartCheck.reset().start(); //重置,发送心跳
}
/**
* 发送数据但连接未建立时进行处理等待重发
* @param {any} message 需要发送的数据
*/
const connecting = message => {
setTimeout(() => {
if (Socket.readyState === 0) {
connecting(message)
} else {
Socket.send(JSON.stringify(message))
}
}, 3000)
}
/**
* 发送数据
* @param {any} message 需要发送的数据
*/
export const sendWSPush = message => {
if (Socket !== null && Socket.readyState === 3) {
Socket.close()
createSocket()
} else if (Socket.readyState === 1) {
Socket.send(JSON.stringify(message))
} else if (Socket.readyState === 0) {
connecting(message)
}
}
/**
*手动关闭服务
*/
export const socketClose = () => {
console.log('手动关闭服务');
if(Socket){
Socket.close()
}
};
/**
* 链接关闭的回调
*/
const oncloseWS = () => {
console.log("WebSocket:已关闭");
heartCheck.reset();//关闭心跳定时器
}
//避免重复连接
var lockReconnect = false, tt;
/**
* websocket重连
*/
function reconnect() {
if (lockReconnect) {
return;
}
lockReconnect = true;
tt && clearTimeout(tt);
tt = setTimeout(function () {
console.log('重连中...');
lockReconnect = false;
createSocket();
}, 4000);
}
/**
* websocket心跳检测
*/
var heartCheck = {
timeout: 15000,
timeoutObj: null,
serverTimeoutObj: null,
reset: function () {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},
start: function () {
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function () {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
Socket.send("ping");
self.serverTimeoutObj = setTimeout(function () { // 如果超过一定时间还没重置,说明后端主动断开了
console.log('关闭服务');
Socket.close();
reconnect(); //重新链接
}, self.timeout)
}, this.timeout)
}
};
界面中使用
//首先要在 vuex 中定义变量
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
message: ""
},
mutations: {
setMessage(state, data) {
state.message = data
},
}
})
//页面组件中使用
import { createSocket, socketClose, sendWSPush } from "@/assets/js/socket";
watch: {
//监听属性,当message值发生变化是,执行其内部的方法,
message(val) {
try {
let msgInfo = JSON.parse(val);
console.log(msgInfo);
} catch (error) {}
},
},
computed: {
//计算属性,使用方式和data中一样,通过this
message() {
return this.$store.state.message;
},
},
//启动连接
createSocket(this.$store); //启动连接
// 断开链接
socketClose();
// 发送消息
sendWSPush({
...
})