websocket心跳检测机制
第一步:在vuex新建websocket.js文件:
export default { namespaced: true, state: { websock: null, url: '', lockReconnect: false, //是否真正建立连接 timeout: 30 * 1000, //30秒一次心跳 timeoutObj: null, //心跳心跳倒计时 serverTimeoutObj: null, //心跳倒计时 timeoutnum: null, //断开 重连倒计时 message: {} }, getters: { message(state) { return state.message } }, mutations: { // 初始化 WEBSOCKET_INIT(state, url) { var that = this state.websock = new WebSocket(url) state.url = url state.websock.onopen = function () { //发送心跳包 that.commit('websocket/start') } state.websock.onmessage = function (res) { if (res.data.indexOf('connectionHolding') > -1 || res.data.indexOf('Connection holding') > -1) { // console.log('心跳响应', new Date().getHours() + ':' + new Date().getMinutes() + ':' + new Date().getSeconds()) } //重置心跳 that.commit('websocket/reset') if (res.data == 'heartCheck' || res.data == 'Connection holding') { return } state.message = res } state.websock.οnerrοr = function () { that.commit('websocket/reconnect') } state.websock.onclose = function () { that.commit('websocket/reconnect') } }, WEBSOCKET_SEND(state, message) { state.websock.send(message) }, //重连 reconnect(state) { var that = this if (state.lockReconnect) { return } state.lockReconnect = true //没连接上会一直重连,设置延迟避免请求过多 state.timeoutnum && clearTimeout(state.timeoutnum) state.timeoutnum = setTimeout(() => { //新连接 that.commit('websocket/WEBSOCKET_INIT', state.url) state.lockReconnect = false }, 5000) }, //重置心跳 reset(state) { clearTimeout(state.timeoutObj) //清除时间 clearTimeout(state.serverTimeoutObj) this.commit('websocket/start') }, //开启心跳 start(state) { var that = this state.timeoutObj && clearTimeout(state.timeoutObj) state.serverTimeoutObj && clearTimeout(state.serverTimeoutObj) state.timeoutObj = setTimeout(() => { //这里发送一个心跳,后端收到后,返回一个心跳消息, if (state.websock.readyState == 1) { //如果连接正常 state.websock.send('') //检测后台心跳响应 state.serverTimeoutObj = setTimeout(() => { state.websock.close() }, state.timeout) } else { //否则重连 that.commit('websocket/reconnect') } }, state.timeout) } }, actions: { WEBSOCKET_INIT({ commit }, url) { commit('WEBSOCKET_INIT', url) }, WEBSOCKET_SEND({ commit }, message) { commit('WEBSOCKET_SEND', message) } } }
第二步:主文件index.vue里面:
mounted() { // 长连接 let userId = localStorage.getItem('userid') const baseURL = process.env.VUE_APP_BASE_API === '' ? `ws:${window.location.hostname}:${window.location.port}/ws/client_${userId}_2` : `ws:${process.env.VUE_APP_BASE_API.split('//')[1] }/ws/client_${userId}_2` this.$store.dispatch('websocket/WEBSOCKET_INIT', baseURL) },
computed: {
listenWebsocket() {
return this.$store.state.websocket.message
}
},
watch: {
// 监听长连接返回数据的变化
listenWebsocket(data) {
let mess = JSON.parse(data.data)
// 需要执行的操作
console.log(mess)
}
}