欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue(element ui)使用websocket及心跳檢測(cè)方式

 更新時(shí)間:2024年07月24日 14:30:40   作者:wangjiecsdn  
這篇文章主要介紹了vue(element ui)使用websocket及心跳檢測(cè)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

業(yè)務(wù)需求

前后端分離,后端java。項(xiàng)目添加websocket消息推送,檢測(cè)到數(shù)據(jù)更改前端進(jìn)行數(shù)據(jù)捕獲,并實(shí)時(shí)渲染。添加心跳檢測(cè)機(jī)制實(shí)時(shí)檢測(cè)連接是否斷開(kāi),斷開(kāi)則重新連接。

項(xiàng)目業(yè)務(wù)

是在消息推送后返回一個(gè)有新消息提醒,然后再調(diào)用一個(gè)列表查詢接口,用vuex維護(hù)起來(lái),放到需要的頁(yè)面進(jìn)行展示及之后的業(yè)務(wù)流程

效果圖(123張圖分別為初始化連接,模擬網(wǎng)絡(luò)斷開(kāi)進(jìn)行重連,模擬網(wǎng)絡(luò)恢復(fù)重新建立連接)

需要連接點(diǎn)(維護(hù)點(diǎn))

  • 登錄后進(jìn)行websocket連接 。
  • 瀏覽器強(qiáng)制刷新時(shí)websocket會(huì)自動(dòng)斷開(kāi),所以需要重新連接
  • 代碼維護(hù)在vuex中

登錄調(diào)用方法

//去vuex,utils里調(diào)用getUserInfo方法
this.$store
.dispatch("utils/getUserInfo", { initSocket: true })
.then((res) => {
});

因?yàn)槲业南⑼扑徒涌谝蕾囉诘卿浗涌诜祷氐膇d,所以我需要再登錄成功回調(diào)后再進(jìn)行我的webwocket連接方法。業(yè)務(wù)不同的小伙伴只需要把此方法放在登錄成功的回調(diào)后即可

vuex里index進(jìn)行注冊(cè)

utils.js代碼塊,主要代碼(備注會(huì)一行一行寫(xiě)清楚,請(qǐng)耐心查看)

//因?yàn)槲冶旧淼臉I(yè)務(wù)是在有新消息收到后再調(diào)用列表查詢的接口,所以會(huì)引入框架的請(qǐng)求方法(無(wú)此需求的小伙伴不用理會(huì))
import * as $http from '@/utils/request'
import { mapGetters } from 'vuex';
const utils = {
  namespaced: true,
  state: {     //聲明變量,跟單頁(yè)面data return聲明一個(gè)意思
    message: [],
    readSysMsgList: [],
    readSysMsgListLength: "",
    wsUrl: '',
    ws_heart: '', // ws心跳定時(shí)器
    lockReconnect: false, //是否真正建立連接
    timeoutnum: null //斷開(kāi) 重連倒計(jì)時(shí)
  },
  getters: {},
  mutations: {
    //vuex突變,拿到維護(hù)的數(shù)據(jù)后交給對(duì)應(yīng)的變量,供頁(yè)面使用(可查看資料vuex用法)
    unReadSysMsg(state, options) {
      state.readSysMsgList = options
    },
    unReadSysMsglenght(state, options) {
      state.readSysMsgListLength = options
    },
  },
  actions: {
    // 獲取連接信息(在登錄接口調(diào)用getUserInfo方法建立連接)
    //getUserInfo有一個(gè)dispatch 參數(shù),此參數(shù)目的為了調(diào)用actions中其他方法
    getUserInfo({ state, commit, dispatch },) {
    //先判斷瀏覽器是否支持WebSocket
      if (typeof WebSocket === "undefined") {
        alert("您的瀏覽器不支持socket");
      } else {
      	//提前判斷 WebSocket是否已經(jīng)建立,避免重復(fù)連接問(wèn)題
        if (this.socket) {
          this.socket.close()
        }
        //WebSocket連接時(shí)我的地址需要拼接用戶的id所以再此進(jìn)行獲取,也就是在登錄時(shí)為啥把getUserInfo放在登錄成功的回調(diào)中,無(wú)此需要的小伙伴可省略
        let id = JSON.parse(localStorage.getItem('loginUserAllInfo')).user.id
        // 實(shí)例化socket (長(zhǎng)連接為ws地址格式)這一步就是建立連接(自行放入url即可)
        this.socket = new WebSocket(`ws://xxx.xxx.xxx/${id}`);
        //new WebSocket有很多內(nèi)置的方法,onopen 就是證明連接已經(jīng)成功,可以在此進(jìn)行心跳檢測(cè)
        this.socket.onopen = () => {
          console.log('websocket已連接');
          //調(diào)用reset方法,reset方法是跟getUserInfo同級(jí),在vuex中需要用dispatch進(jìn)行調(diào)用(可參考actions里第二行注釋解釋,必須得有接收參數(shù))。跟單頁(yè)面中的this.reset()同理
          dispatch("reset")
          //本項(xiàng)目業(yè)務(wù),建立連接后先進(jìn)行列表查詢
          $http.get("/task/sysMessage/getUnReadSysMsg").then((res) => {
            console.log(res.data)
            //列表查詢的結(jié)果拿commit存到vuex當(dāng)中,然后再給了state中的變量,到時(shí)候頁(yè)面就可以直接拿到了。比如先把unReadSysMsg存起來(lái),給了readSysMsgList ,然后頁(yè)面獲取數(shù)據(jù)的時(shí)候就可以this.readSysMsgList 稍后會(huì)有頁(yè)面展示的代碼
            commit("unReadSysMsg", res.data);
            commit("unReadSysMsglenght", res.data.length);
          })
        };
        // 監(jiān)聽(tīng)socket消息(主要內(nèi)置方法,收到消息后會(huì)進(jìn)行監(jiān)聽(tīng)接收)
        this.socket.onmessage = (msg) => {
          // console.log('接收到新消息--------' + msg.data)
          //同樣調(diào)用reset進(jìn)行心跳檢測(cè)重置
          dispatch("reset")
          
          //本項(xiàng)目業(yè)務(wù),主要心跳檢測(cè),我會(huì)在start方法里每隔30秒主動(dòng)進(jìn)行ping推送,看連接是否還存在,如果接收到pong到pong就證明是因?yàn)槲抑鲃?dòng)推送消息拿到的監(jiān)聽(tīng)結(jié)果,就不需要處理。如果接收到非pong則證明是后端有新消息推送過(guò)來(lái),重新進(jìn)行列表查詢,刷新數(shù)據(jù)
          if (msg.data == "pong") {
          } else {
          //直接返回?cái)?shù)據(jù)的可避免此操作,直接拿到msg,commit存儲(chǔ)好就可
            $http.get("/task/sysMessage/getUnReadSysMsg").then((res) => {
              commit("unReadSysMsg", res.data);
              commit("unReadSysMsglenght", res.data.length);
              console.log(res.data)
            })
          }
        };
        // 監(jiān)聽(tīng)socket錯(cuò)誤信息(websocket斷開(kāi)會(huì)進(jìn)入此方法,需要進(jìn)行重連)
        this.socket.onclose = function (e) {
          console.log('關(guān)閉了')
          //斷開(kāi)連接后調(diào)用reconnect進(jìn)行重新連接
          dispatch("reconnect")
        };
        // WebSocket發(fā)生錯(cuò)誤
        this.socket.onerror = function (e) {
         //斷開(kāi)連接后調(diào)用reconnect進(jìn)行重新連接
          dispatch("reconnect")
          console.log("WebSocket發(fā)生錯(cuò)誤");
        };
      }
    },
    //重新連接(斷開(kāi)跟錯(cuò)誤后都需要進(jìn)行重連操作)
    reconnect({ dispatch }) {
      var that = this;
      if (that.lockReconnect) {
        // 是否真正建立連接
        return;
      }
      that.lockReconnect = true;
      //沒(méi)連接上會(huì)一直重連,設(shè)置延遲避免請(qǐng)求過(guò)多
      that.timeoutnum && clearTimeout(that.timeoutnum);
      // 如果到了這里斷開(kāi)重連的倒計(jì)時(shí)還有值的話就清除掉
      that.timeoutnum = setTimeout(function () {
        console.log('重啟中')
        //然后新連接(dispatch照樣進(jìn)行方法getUserInfo的調(diào)用)
        dispatch('getUserInfo')
        that.lockReconnect = false;
      }, 60000);
    },
    //建立連接及有新消息接收后進(jìn)行心跳重置
    reset({ dispatch }) {
      //重置心跳
      var that = this;
      //清除時(shí)間(清除心跳計(jì)時(shí))
      clearInterval(that.ws_heart)
      //重啟心跳
      dispatch("start")
    },
    //心跳檢測(cè)
    start({ dispatch }) {
    //實(shí)時(shí)推送ping消息,查看連接是否斷開(kāi)
      this.ws_heart = setInterval(() => {
        let actions = "ping"
        this.socket.send(JSON.stringify(actions));
      }, 30000)
    },
  }
}
export default utils

以上主要代碼已完畢

app.vue中再次調(diào)用getUserInfo方法,避免瀏覽器強(qiáng)制刷新導(dǎo)致斷開(kāi)連接

 mounted() {
 //退出登錄后會(huì)把localStorage清空,避免控制臺(tái)報(bào)錯(cuò)
    if (JSON.parse(localStorage.getItem('loginUserAllInfo'))) {
      let userId = JSON.parse(localStorage.getItem('loginUserAllInfo')).user.id
      if (userId) {
        this.$store
          .dispatch("utils/getUserInfo", { initSocket: true })
          .then(() => {
          });
      }
    } else {
    }
  },

頁(yè)面使用(附效果圖)

//頁(yè)面可直接使用數(shù)據(jù),放到想用到的地方
	<template>
	<div>
	{{this.readSysMsgList}}
	</div>
	</template>
//引入vuex
import { mapActions, mapState } from 'vuex'  
export default {
 computed: {
    //獲取vuex中存放的數(shù)據(jù)
    ...mapState("utils", ["readSysMsgList","readSysMsgListLength"]),
  },
} 

//貼入本項(xiàng)目的業(yè)務(wù)代碼(主要看我el-table遍歷data   :data="this.readSysMsgList"直接就可渲染)
<template>
  <div class="navbar">
 <el-dialog :modal="false" title="您的消息" :visible.sync="moreFlag" class="tableLocation">
      <el-table :data="this.readSysMsgList" height="200"  @row-click="rowClick">
        <el-table-column align="center" width="40">
          <template slot-scope="scope">
            <i v-if="scope.row.messageType == '1'" class="el-icon-warning" style="color:#d0183d"></i>
            <i v-else class="el-icon-warning" style="color:#45d720"></i>
          </template>
        </el-table-column>
        <el-table-column property="messageType" label="消息類(lèi)型" width="70">
          <template slot-scope="scope">
            <div v-if="scope.row.messageType == '1'">新任務(wù)</div>
            <div v-else-if="scope.row.orderStatus == '2'">待跟進(jìn)</div>
            <div v-else-if="scope.row.orderStatus == '3'">待執(zhí)行</div>
          </template>
        </el-table-column>
        <el-table-column property="content" label="消息內(nèi)容"></el-table-column>
      </el-table>
    </el-dialog>
  </div>
</template>

難點(diǎn)在于連接成功后onopen、onmessage方法心跳檢測(cè),以及onclose、onerror斷開(kāi)連接后進(jìn)行重連。這塊還添加了自己本身的另一個(gè)短連接口業(yè)務(wù),所以會(huì)難梳理。不懂的還請(qǐng)vuex里代碼每行注釋進(jìn)行通讀。

通俗講就是new WebSocket 建立連接后,在自帶的方法里onopen(建立連接)、onmessage(收到推送消息)、onclose(連接斷開(kāi))、onerror(連接發(fā)生錯(cuò)誤)進(jìn)行自己的業(yè)務(wù)流程。

注:此方法為原生方法,如感覺(jué)繁瑣還可查看"socket.io-client","vue-socket.io"插件使用,但我本項(xiàng)目用的時(shí)候不知是不是因?yàn)楹笈_(tái)是java寫(xiě)的,在后端給的地址基礎(chǔ)上,會(huì)自動(dòng)拼接EIO = 3&transport = websocket這個(gè)參數(shù),導(dǎo)致匹配不到接口報(bào)404,讓后端把后幾個(gè)參數(shù)寫(xiě)死解決方法也沒(méi)走通,又回到了原生方法,有興趣的可自行嘗試

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue @click與@click.native,及vue事件機(jī)制的使用分析

    vue @click與@click.native,及vue事件機(jī)制的使用分析

    這篇文章主要介紹了vue @click與@click.native,及vue事件機(jī)制的使用分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue-router判斷頁(yè)面未登錄自動(dòng)跳轉(zhuǎn)到登錄頁(yè)的方法示例

    vue-router判斷頁(yè)面未登錄自動(dòng)跳轉(zhuǎn)到登錄頁(yè)的方法示例

    這篇文章主要介紹了vue-router判斷頁(yè)面未登錄自動(dòng)跳轉(zhuǎn)到登錄頁(yè)的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • 關(guān)于Vue3過(guò)渡動(dòng)畫(huà)的踩坑記錄

    關(guān)于Vue3過(guò)渡動(dòng)畫(huà)的踩坑記錄

    在開(kāi)發(fā)中我們想要給一個(gè)組件的顯示和消失添加某種過(guò)渡動(dòng)畫(huà),可以很好的增加用戶體驗(yàn),下面這篇文章主要給大家介紹了關(guān)于Vue3過(guò)渡動(dòng)畫(huà)踩坑的相關(guān)資料,需要的朋友可以參考下
    2021-12-12
  • 12 種使用Vue 的最佳做法

    12 種使用Vue 的最佳做法

    這篇文章主要介紹了12 種使用Vue 的最佳做法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • 詳解Vue-axios 設(shè)置請(qǐng)求頭問(wèn)題

    詳解Vue-axios 設(shè)置請(qǐng)求頭問(wèn)題

    這篇文章主要介紹了Vue-axios 設(shè)置請(qǐng)求頭問(wèn)題,文中給大家提到了axios設(shè)置請(qǐng)求頭內(nèi)容的方法,需要的朋友可以參考下
    2018-12-12
  • 去除element-ui下拉框的下拉箭頭的實(shí)現(xiàn)

    去除element-ui下拉框的下拉箭頭的實(shí)現(xiàn)

    我們最開(kāi)始拿到的element-ui是帶有下拉箭頭的,那么如何去除element-ui下拉框的下拉箭頭的實(shí)現(xiàn),本文就詳細(xì)的介紹一下,感興趣的可以了解一下
    2023-08-08
  • vue中優(yōu)雅實(shí)現(xiàn)數(shù)字遞增特效的詳細(xì)過(guò)程

    vue中優(yōu)雅實(shí)現(xiàn)數(shù)字遞增特效的詳細(xì)過(guò)程

    項(xiàng)目中需要做數(shù)字滾動(dòng)增加的效果,一開(kāi)始很懵,研究了一下原理,發(fā)現(xiàn)很簡(jiǎn)單,下面這篇文章主要給大家介紹了關(guān)于vue中優(yōu)雅實(shí)現(xiàn)數(shù)字遞增特效的詳細(xì)過(guò)程,需要的朋友可以參考下
    2022-12-12
  • vue項(xiàng)目中v-model父子組件通信的實(shí)現(xiàn)詳解

    vue項(xiàng)目中v-model父子組件通信的實(shí)現(xiàn)詳解

    vue.js,是一個(gè)構(gòu)建數(shù)據(jù)驅(qū)動(dòng)的 web 界面的庫(kù)。Vue.js 的目標(biāo)是通過(guò)盡可能簡(jiǎn)單的 API 實(shí)現(xiàn)響應(yīng)的數(shù)據(jù)綁定和組合的視圖組件。下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目中v-model父子組件通信實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下。
    2017-12-12
  • element-ui el-select下拉框el-date-picker彈出框定位問(wèn)題解決方案(推薦)

    element-ui el-select下拉框el-date-picker彈出框定位問(wèn)題解決方案(推薦)

    項(xiàng)目開(kāi)發(fā)過(guò)程中發(fā)現(xiàn)el-select和el-date-picker彈出框顯示時(shí)候,滾動(dòng)屏幕,導(dǎo)致彈出框定位出現(xiàn)問(wèn)題,這篇文章主要介紹了element-ui el-select下拉框el-date-picker彈出框定位問(wèn)題解決方案(推薦),需要的朋友可以參考下
    2024-07-07
  • vue package.json文件的使用及說(shuō)明

    vue package.json文件的使用及說(shuō)明

    `package.json`是Node.js和npm項(xiàng)目的核心配置文件,定義了項(xiàng)目的元數(shù)據(jù)和依賴項(xiàng),在Vue項(xiàng)目中,它管理依賴、提供腳本命令、存儲(chǔ)項(xiàng)目信息,并通過(guò)語(yǔ)義化版本控制確保項(xiàng)目穩(wěn)定
    2025-01-01

最新評(píng)論