最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3實(shí)現(xiàn)SSE(Server-Sent?Events)連接

 更新時(shí)間:2024年10月28日 15:06:16   作者:算是難了  
SSE?是一種允許服務(wù)器向?yàn)g覽器推送事件的技術(shù),這篇文章主要為大家詳細(xì)介紹了如何通過vue3實(shí)現(xiàn)SSE(Server-Sent?Events)連接,有需要的小伙伴可以了解下

在現(xiàn)代 web 開發(fā)中,Server-Sent Events (SSE) 是一種輕量級(jí)的技術(shù),允許服務(wù)器通過 HTTP 持久連接向客戶端推送實(shí)時(shí)更新。在本文中,我們將探討如何在 Vue 3 應(yīng)用中實(shí)現(xiàn) SSE 連接,并處理接收到的消息。

什么是 SSE

SSE 是一種允許服務(wù)器向?yàn)g覽器推送事件的技術(shù)。與 WebSocket 不同,SSE 是單向的:服務(wù)器可以向客戶端發(fā)送數(shù)據(jù),而客戶端不能直接向服務(wù)器發(fā)送數(shù)據(jù)。SSE 適用于需要實(shí)時(shí)更新的應(yīng)用,比如聊天應(yīng)用、通知系統(tǒng)和實(shí)時(shí)數(shù)據(jù)監(jiān)控。

核心代碼示例

    let retryCount = 0;
    const maxRetries = 5; // 最大重試次數(shù)
    const maxRetryDelay = 30000; // 最大重連時(shí)間,30秒  
 
    // 當(dāng)前用戶身份
    const username = ref("");
 
    // 初始化 SSE 連接
    let eventSource: EventSource;
    const initializeSSE = () => {
      // 連接SSE
      // 定義SSE鏈接參數(shù)
      let url =
        import.meta.env.VITE_BASE_API +
        "/notification/socket_connection?username=" +
        encodeURIComponent(username.value);
      // 監(jiān)聽連接打開事件
      eventSource = new EventSource(url);
      eventSource.onopen = () => {
        console.log("建立 SSE 連接成功");
      };
 
      // 監(jiān)聽消息事件
      eventSource.onmessage = event => {
        // 收到消息
        chunk.value = JSON.parse(event.data);
        console.log("收到的類型:", chunk.value.notice_type, 222);
 
        // 根據(jù) notice_type 處理不同的通知類型
        switch (chunk.value.notice_type) {
          case 0:
            userThumNotification();
            break;
          case 1:
            userStarNotification();
            break;
          case 2:
            userComNotification();
            break;
          case 3:
            systemNotice();
            break;
          case 4:
            managerNotice();
            break;
          case 5:
            // 暫時(shí)擱置,用其他方法代替
            if (storedRole.value !== "user") {
              reportEmail();
            }
            break;
          default:
            console.warn("未知通知類型:", chunk.value.notice_type);
        }
        showNotify();
      };
 
      // 監(jiān)聽錯(cuò)誤事件
      eventSource.onerror = () => {
        console.error("SSE 連接發(fā)生錯(cuò)誤,嘗試重連...");
        eventSource.close(); // 關(guān)閉當(dāng)前連接
        handleReconnect(); // 嘗試重連
      };
    };
 
    const handleReconnect = () => {
      if (username.value !== "") {
        console.log("連接已關(guān)閉, 嘗試重新連接");
        if (retryCount < maxRetries) {
          retryCount++;
          const retryDelay = Math.min(
            1000 * Math.pow(2, retryCount),
            maxRetryDelay
          ); // 計(jì)算重連延遲
          setTimeout(initializeSSE, retryDelay);
        } else {
          showToast("網(wǎng)絡(luò)連接不穩(wěn)定,請(qǐng)檢查網(wǎng)絡(luò)或重新登錄。");
          console.log("已達(dá)到最大重試次數(shù),停止重連。");
        }
      }
    };

舉例:全局狀態(tài)管理消息總數(shù)

假設(shè)我們有三種通知類型:

點(diǎn)贊、評(píng)論、收藏

在userStore中進(jìn)行全局狀態(tài)管理,動(dòng)態(tài)更新消息數(shù)量:

import { defineStore } from "pinia";
import { ref, computed } from "vue";
import { getManagerNotification } from "@/api/user";
import { getreportEmail } from "@/api/user";
import { getSystemNotification } from "@/api/user";
import {
  getUserThumNotification,
  getUserComNotification,
  getUserStarNotification
} from "@/api/user";
import { showToast } from "vant";
// import { showNotify } from "vant";
//用戶信息管理
export const useInformation = defineStore(
  "notication",
  () => {
    let retryCount = 0;
    const maxRetries = 5; // 最大重試次數(shù)
    const maxRetryDelay = 30000; // 最大重連時(shí)間,30秒
 
    // 是否顯示SSE彈框
    const noticeShow = ref(false);
    // 接收到的SSE消息
    const chunk = ref();
 
    // 當(dāng)前用戶身份
    const username = ref("");
    const storedRole = ref("");
 
    // 系統(tǒng)最新一條通知
    const systemData = ref({});
    // 管理員最新一條通知
    const managerData = ref({});
 
    // 用戶未讀消息
    const thumb = ref(0);
    const comment = ref(0);
    const star = ref(0);
    // 管理員未讀消息數(shù)
    const manager_count = ref(0);
    // 系統(tǒng)未讀消息數(shù)
    const system_count = ref(0);
    // 郵箱未讀消息數(shù)
    const email_count = ref(0);
 
    // 互動(dòng)通知
    // 默認(rèn)活躍的tab欄
    const activeTab = ref(0);
 
    // 總數(shù)
    // 使用計(jì)算屬性動(dòng)態(tài)獲取 total
    const total = computed(() => {
      return (
        thumb.value +
        comment.value +
        star.value +
        manager_count.value +
        system_count.value
      );
    });
 
    // 通用的獲取未讀通知數(shù)量的函數(shù)
    const fetchNotificationCount = async (fetchFunction, refData, refCount) => {
      try {
        const res = await fetchFunction({ page: 1, limit: 1 });
        if (refData != null) {
          refData.value = res.data;
        }
        refCount.value = res.data.unread_count;
      } catch (error) {
        console.error("獲取通知時(shí)發(fā)生錯(cuò)誤:", error);
      }
    };
 
    // 獲取系統(tǒng)消息
    const systemNotice = () => {
      fetchNotificationCount(getSystemNotification, systemData, system_count);
      console.log(system_count.value);
    };
 
    // 獲取管理員消息
    const managerNotice = () => {
      fetchNotificationCount(
        getManagerNotification,
        managerData,
        manager_count
      );
    };
 
    // 獲取點(diǎn)贊通知的未讀消息數(shù)量
    const userThumNotification = () => {
      fetchNotificationCount(getUserThumNotification, null, thumb);
    };
 
    // 獲取評(píng)論通知的未讀消息數(shù)量
    const userComNotification = () => {
      fetchNotificationCount(getUserComNotification, null, comment);
    };
 
    // 獲取收藏通知的未讀消息數(shù)量
    const userStarNotification = () => {
      fetchNotificationCount(getUserStarNotification, null, star);
    };
 
    // 獲取舉報(bào)郵箱消息
    const reportEmail = async () => {
      fetchNotificationCount(getreportEmail, null, email_count);
    };
 
    // 獲取頁(yè)面消息
    const userNotice = async () => {
      await Promise.all([
        userThumNotification(),
        userComNotification(),
        userStarNotification()
      ]);
    };
 
    // 初始化函數(shù)
    const initNotifications = () => {
      console.log(username, "哈哈哈紅紅火火恍恍惚惚");
      systemNotice();
      managerNotice();
      userNotice();
      if (storedRole.value !== "user") {
        reportEmail();
      }
      // 打印 total,確保它是最新的
      console.log("Total after initialization:", total.value);
    };
 
    const showNotify = () => {
      noticeShow.value = true;
      setTimeout(() => {
        noticeShow.value = false;
      }, 3000);
    };
 
    // 初始化 SSE 連接
    let eventSource: EventSource;
    const initializeSSE = () => {
      // 連接SSE
      // 定義SSE鏈接參數(shù)
      let url =
        import.meta.env.VITE_BASE_API +
        "/notification/socket_connection?username=" +
        encodeURIComponent(username.value);
      // 監(jiān)聽連接打開事件
      eventSource = new EventSource(url);
      eventSource.onopen = () => {
        console.log("建立 SSE 連接成功");
      };
 
      // 監(jiān)聽消息事件
      eventSource.onmessage = event => {
        // 收到消息
        chunk.value = JSON.parse(event.data);
        console.log("收到的類型:", chunk.value.notice_type, 222);
 
        // 根據(jù) notice_type 處理不同的通知類型
        switch (chunk.value.notice_type) {
          case 0:
            userThumNotification();
            break;
          case 1:
            userStarNotification();
            break;
          case 2:
            userComNotification();
            break;
          case 3:
            systemNotice();
            break;
          case 4:
            managerNotice();
            break;
          case 5:
            // 暫時(shí)擱置,用其他方法代替
            if (storedRole.value !== "user") {
              reportEmail();
            }
            break;
          default:
            console.warn("未知通知類型:", chunk.value.notice_type);
        }
        showNotify();
      };
 
      // 監(jiān)聽錯(cuò)誤事件
      eventSource.onerror = () => {
        console.error("SSE 連接發(fā)生錯(cuò)誤,嘗試重連...");
        eventSource.close(); // 關(guān)閉當(dāng)前連接
        handleReconnect(); // 嘗試重連
      };
    };
 
    const handleReconnect = () => {
      if (username.value !== "") {
        console.log("連接已關(guān)閉, 嘗試重新連接");
        if (retryCount < maxRetries) {
          retryCount++;
          const retryDelay = Math.min(
            1000 * Math.pow(2, retryCount),
            maxRetryDelay
          ); // 計(jì)算重連延遲
          setTimeout(initializeSSE, retryDelay);
        } else {
          showToast("網(wǎng)絡(luò)連接不穩(wěn)定,請(qǐng)檢查網(wǎng)絡(luò)或重新登錄。");
          console.log("已達(dá)到最大重試次數(shù),停止重連。");
        }
      }
    };
 
    // 關(guān)閉 SSE 連接
    const closeConnection = () => {
      eventSource.close();
      console.log("SSE 連接已手動(dòng)關(guān)閉");
    };
 
    // 重置
    const removeNotification = () => {
      systemData.value = {};
      managerData.value = {};
      thumb.value = 0;
      star.value = 0;
      manager_count.value = 0;
      system_count.value = 0;
      email_count.value = 0;
      activeTab.value = 0;
    };
 
    return {
      username,
      storedRole,
      systemData,
      managerData,
      manager_count,
      system_count,
      email_count,
      thumb,
      comment,
      star,
      total,
      activeTab,
      noticeShow,
      chunk,
      systemNotice,
      managerNotice,
      userThumNotification,
      userComNotification,
      userStarNotification,
      reportEmail,
      closeConnection,
      removeNotification,
      initializeSSE,
      initNotifications
    };
  },
  {
    persist: true
  }
);

到此這篇關(guān)于Vue3實(shí)現(xiàn)SSE(Server-Sent Events)連接的文章就介紹到這了,更多相關(guān)Vue3 SSE連接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于Vue?CLI3中啟動(dòng)cli服務(wù)參數(shù)說明

    關(guān)于Vue?CLI3中啟動(dòng)cli服務(wù)參數(shù)說明

    這篇文章主要介紹了關(guān)于Vue?CLI3中啟動(dòng)cli服務(wù)參數(shù)說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • VueX?mapGetters獲取Modules中的Getters方式

    VueX?mapGetters獲取Modules中的Getters方式

    這篇文章主要介紹了VueX?mapGetters獲取Modules中的Getters方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Vuex中this.$store.commit()和this.$store.dispatch()區(qū)別說明

    Vuex中this.$store.commit()和this.$store.dispatch()區(qū)別說明

    這篇文章主要介紹了Vuex中this.$store.commit()和this.$store.dispatch()區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • 公共組件父子依賴調(diào)用及子校驗(yàn)父條件問題解決

    公共組件父子依賴調(diào)用及子校驗(yàn)父條件問題解決

    這篇文章主要介紹了如何解決公共組件父子組件依賴調(diào)用和子組件校驗(yàn)父組件條件的問題,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • Vue使用html2canvas和jspdf實(shí)現(xiàn)PDF文件導(dǎo)出

    Vue使用html2canvas和jspdf實(shí)現(xiàn)PDF文件導(dǎo)出

    這篇文章主要為大家詳細(xì)介紹了Vue如何使用html2canvas和jspdf實(shí)現(xiàn)PDF文件導(dǎo)出功能并設(shè)置頁(yè)面大小及方向,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-01-01
  • 如何去掉ElementUI Table的hover變色問題

    如何去掉ElementUI Table的hover變色問題

    這篇文章主要介紹了如何去掉ElementUI Table的hover變色問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue實(shí)現(xiàn)簡(jiǎn)單計(jì)算商品價(jià)格

    vue實(shí)現(xiàn)簡(jiǎn)單計(jì)算商品價(jià)格

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)簡(jiǎn)單計(jì)算商品價(jià)格,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • vue中keep-alive組件的用法示例

    vue中keep-alive組件的用法示例

    眾所周知keep-alive是Vue提供的一個(gè)抽象組件,主要是用來對(duì)組件進(jìn)行緩存,從而做到節(jié)省性能,這篇文章主要給大家介紹了關(guān)于vue中keep-alive組件用法的相關(guān)資料,需要的朋友可以參考下
    2021-05-05
  • Element中table組件(el-table)右側(cè)滾動(dòng)條空白占位處理

    Element中table組件(el-table)右側(cè)滾動(dòng)條空白占位處理

    當(dāng)我設(shè)置了max-height,就會(huì)在表格右側(cè)出現(xiàn)一列空白的占位,本文主要介紹了Element中table組件(el-table)右側(cè)滾動(dòng)條空白占位處理,感興趣的可以了解一下
    2023-09-09
  • Vue elementUI 自定義表單模板組件功能實(shí)現(xiàn)

    Vue elementUI 自定義表單模板組件功能實(shí)現(xiàn)

    在項(xiàng)目開發(fā)中,我們會(huì)遇到這種需求,在管理后臺(tái)添加自定義表單,在指定的頁(yè)面使用定義好的表單,這篇文章主要介紹了Vue elementUI 自定義表單模板組件,需要的朋友可以參考下
    2022-12-12

最新評(píng)論

托里县| 建平县| 琼结县| 军事| 和政县| 平湖市| 宁津县| 轮台县| 淮安市| 阿城市| 乌审旗| 环江| 丰县| 肥西县| 东宁县| 宁河县| 尼玛县| 德清县| 万全县| 隆德县| 玉门市| 石河子市| 兴和县| 开原市| 邵武市| 富锦市| 荥经县| 逊克县| 余庆县| 磴口县| 北流市| 夏津县| 白沙| 淄博市| 彭阳县| 沾化县| 宁城县| 夏津县| 雅江县| 东乡族自治县| 霍山县|