websocket心跳檢測機制
阿新 • • 發佈:2021-07-13
第一步:在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(){ returnthis.$store.state.websocket.message } }, watch:{ //監聽長連線返回資料的變化 listenWebsocket(data){ letmess=JSON.parse(data.data) // 需要執行的操作 console.log(mess) } }