自学内容网 自学内容网

Vue3 实现 SSE 连接

在现代 web 开发中,Server-Sent Events (SSE) 是一种轻量级的技术,允许服务器通过 HTTP 持久连接向客户端推送实时更新。在本文中,我们将探讨如何在 Vue 3 应用中实现 SSE 连接,并处理接收到的消息。

什么是 SSE?

SSE 是一种允许服务器向浏览器推送事件的技术。与 WebSocket 不同,SSE 是单向的:服务器可以向客户端发送数据,而客户端不能直接向服务器发送数据。SSE 适用于需要实时更新的应用,比如聊天应用、通知系统和实时数据监控。

核心代码示例:


let eventSource;
// 从后端获取的用户名,使用该用户名建立连接,当然也可以是id...
let username = "20221"
// 初始化 SSE 连接
const initializeSSE = () => {
  eventSource = new EventSource(`${import.meta.env.VITE_BASE_API}/notification/socket_connection?username=${encodeURIComponent(username)}`);

  eventSource.onopen = () => {
    console.log('SSE 连接成功');
  };

  eventSource.onmessage = (event) => {
    console.log('收到消息:', event.data);
    const chunk = JSON.parse(event.data);
    // 下面是对接收的数据进行任意操作
    // ....
  };

  eventSource.onclose = () => {
    console.log('连接已关闭');
  };
};

// 清理连接
const closeConnection = () => {
  if (eventSource) {
    eventSource.close();
    console.log('SSE 连接已手动关闭');
  }
};

// 组件挂载时初始化连接
onMounted(initializeSSE);

// 组件卸载时关闭连接
onUnmounted(closeConnection);

举例:全局状态管理消息总数

假设我们有三种通知类型:

点赞、评论、收藏

在userStore中进行全局状态管理,动态更新消息数量:

import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
import { getUserThumNotification, getUserComNotification, getUserStarNotification } from '@/api/notifications'; // 假设这些是您的 API 函数

export const useInformation = defineStore("notification", () => {
  // 用户未读消息
  const thumb = ref(0);
  const comment = ref(0);
  const star = ref(0);

  // 用户消息未读数
  const total = computed(() => thumb.value + comment.value + star.value);

  // 获取未读通知的函数
  const fetchNotificationCount = async (fetchFunction, refVariable) => {
    const response = await fetchFunction({ page: 1, limit: 1 });
    const unreadCount = response.data.unread_count;
    if (unreadCount !== undefined) {
      refVariable.value = unreadCount;
    }
  };

  // 获取点赞、评论和收藏通知的未读消息数量
  const userThumNotification = () => fetchNotificationCount(getUserThumNotification, thumb);
  const userComNotification = () => fetchNotificationCount(getUserComNotification, comment);
  const userStarNotification = () => fetchNotificationCount(getUserStarNotification, star);

  // 初始化消息
  const initNotifications = async () => {
    await Promise.all([userThumNotification(), userComNotification(), userStarNotification()]);
    console.log("Total after initialization:", total.value);
  };

  // 连接SSE
  const sseChatParams = {
    onopen: () => {
      console.log("建立无敌 SSE 连接成功");
    },
    url: `${import.meta.env.VITE_BASE_API}/notification/socket_connection?username=${encodeURIComponent(username)}`,
    onmessage: async (event) => {
      console.log("收到消息:", event.data);
      const chunk = JSON.parse(event.data);

      switch (chunk.notice_type) {
        case "0":
          await userThumNotification();
          break;
        case "1":
          await userStarNotification();
          break;
        case "2":
          await userComNotification();
          break;
        default:
          console.warn("未知通知类型:", chunk.notice_type);
      }
    }
  };

  // 初始化 SSE 连接
  let eventSource;
  const initializeSSE = () => {
    eventSource = new EventSource(sseChatParams.url);
    eventSource.onopen = sseChatParams.onopen;
    eventSource.onmessage = sseChatParams.onmessage;
    eventSource.onerror = (event) => {
      console.error("SSE 连接发生错误:", event);
    };
  };

  // 执行初始化
  initNotifications();
  initializeSSE();

  return {
    total,
    userThumNotification,
    userComNotification,
    userStarNotification,
  };
}, {
  persist: true
});


原文地址:https://blog.csdn.net/2301_76662406/article/details/142906427

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!