vue3使用SSE实现前端全局事件通讯方式

 更新时间:2025年10月15日 08:38:42   作者:你的眼睛會笑  
文章介绍了使用Vue3和VueUse实现基于SSE(Server-Sent Events)的全局事件通讯系统,SSE具有单向通信、基于HTTP、自动重连和轻量级等特点,适合实时性要求高的应用,实现方案包括订阅消息、取消订阅和关闭连接等功能

vue3 SSE实现前端全局事件通讯

什么是SSE (useEventSource)

SSE(Server-Sent Events)是一种基于HTTP的服务器推送技术,允许服务器单向向客户端发送事件。相比WebSocket,SSE具有以下特点:

  • 单向通信(服务器→客户端)
  • 基于HTTP协议,无需额外协议
  • 自动重连机制
  • 轻量级,实现简单

为什么选择SSE作为全局通讯方案

  • 实时性 :服务器可以即时推送数据到所有客户端
  • 低开销 :相比轮询,减少了不必要的请求
  • 自动重连 :内置连接恢复机制
  • 兼容性 :现代浏览器普遍支持

实现方案

以下是基于Vue 3和VueUse的SSE全局通讯实现:

import { getToken } from "@/store/modules/auth/helper";
import { useEventSource } from '@vueuse/core'
import { watch } from "vue";

const baseURL = 'https://xxxxxxxxxxxx.com/api'
let eventSource: ReturnType<typeof useEventSource> | null = null;
const callbacks = new Set<(data: any) => void>();

// 初始化SSE连接
export const initSSE = () => {
    if (eventSource) return;

    const token = getToken();
    const url = `${baseURL}/sse?Authorization=${token}`;

    eventSource = useEventSource(url, [], {
        autoReconnect: {
            retries: 5,
            delay: 5000,
            onFailed() {
                console.error('SSE连接失败');
            }
        }
    });

    // 错误处理
    watch(eventSource.error, (err) => {
        if (err) console.error('SSE连接错误:', err);
    });

    // 消息处理
    watch(eventSource.data, (msg) => {
        if (msg && msg !== 'heartbeat') {
            try {
                const data = JSON.parse(msg);
                callbacks.forEach(cb => cb(data)); // 通知所有订阅者
            } catch (e) {
                console.error('SSE数据解析错误:', e);
            }
        }
    });
};

核心功能实现

  1. 订阅消息
// 添加消息监听
export function addListener(callback: (data: any) => void) {
    callbacks.add(callback);
    return () => removeListener(callback); // 返回取消订阅函数
}
  1. 取消订阅
// 移除消息监听
function removeListener(callback: (data: any) => void) {
    callbacks.delete(callback);
}
  1. 关闭连接
// 关闭SSE连接
export function closeSse() {
    eventSource?.close();
    eventSource = null;
    callbacks.clear();
}

在Vue组件中使用

  1. 初始化连接
// 在应用初始化时调用
import { initSSE } from '@/utils/sse';

// 启动SSE连接
initSSE();
  1. 订阅消息
import { addListener,closeSse } from '@/utils/sse';

// 组件内订阅
const unsubscribe = addListener((data) => {
    console.log('收到消息:', data);
    // 处理业务逻辑...
});

// 组件销毁时取消订阅
onUnmounted(() => {
    closeSse();
});

实际应用场景

  1. 实时通知系统 :新消息提醒、系统公告等
  2. 数据监控 :实时展示服务器状态、监控数据
  3. 协同编辑 :多人协作时的内容同步
  4. 任务进度更新 :长时间任务的进度通知

性能优化建议

  1. 心跳机制 :服务器定期发送心跳包保持连接
  2. 消息压缩 :对大消息进行压缩处理
  3. 批量发送 :合并多个小消息为一次发送
  4. 连接共享 :多个组件复用同一个连接

完整代码

// sse.ts
import { getToken } from "@/store/modules/auth/helper";
import { useEventSource } from '@vueuse/core'
import { watch } from "vue";
const baseURL =  'http://xxxxxxxxxx'
let eventSource:any = null;
const callbacks: Set<(data: any) => void> = new Set();
export const initSSE = () => {
    if (eventSource) return;

    const token = getToken();
    const url = `${baseURL}/sse?Authorization=${token}`;

     eventSource = useEventSource(url, [], {
        autoReconnect: {
            retries: 5,
            delay: 5000,
            onFailed() {
                console.log('Failed to connect after 5 retries');
            }
        }
    });

    const { data, error } = eventSource;
    watch(error, (err) => {
        if (err) {
            console.error('SSE连接错误:', err);
            error.value = null;
        }
    });

    watch(data, (msg) => {
        if (msg) {
            console.log('SSE接收到消息:', msg);
                try {
                    const parsedData = JSON.parse(msg);
                    callbacks.forEach(cb => cb(parsedData));
                } catch (e) {
                    console.error('SSE数据解析错误:', e);
                }
            data.value = null;
        }
    });



};

export function addListener(callback: (data: any) => void) {
    callbacks.add(callback);
    return () => removeListener(callback);
}

function removeListener(callback: (data: any) => void) {
    callbacks.delete(callback);
}

export function closeSse() {
    // eventSource?.close();
    eventSource = null;
    callbacks.clear();
}

总结

SSE提供了一种简单高效的服务器推送方案,非常适合构建实时性要求较高的应用。通过全局管理SSE连接,可以实现跨组件的实时通讯,减少重复连接,提高应用性能。

本文介绍的实现方案具有以下优点:

  • 基于VueUse,代码简洁
  • 支持自动重连
  • 全局单例管理
  • 易于集成到现有项目
  • 对于需要双向通信的场景,可以考虑结合WebSocket或保留传统的HTTP轮询作为补充。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • electron-builder打包vue2项目问题总结

    electron-builder打包vue2项目问题总结

    这篇文章主要介绍了electron-builder打包vue2项目问题总结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-08-08
  • vue插件开发之使用pdf.js实现手机端在线预览pdf文档的方法

    vue插件开发之使用pdf.js实现手机端在线预览pdf文档的方法

    这篇文章主要介绍了vue插件开发之使用pdf.js实现手机端在线预览pdf文档的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • vue中使用 pako.js 解密 gzip加密字符串的方法

    vue中使用 pako.js 解密 gzip加密字符串的方法

    这篇文章主要介绍了vue项目中 使用 pako.js 解密 gzip加密字符串 的方法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-06-06
  • vue项目中echarts自适应问题的高级解决过程

    vue项目中echarts自适应问题的高级解决过程

    虽然老早就看过很多echarts的例子,但自己接触的项目中一直都没有真正用到过,直到最近才开始真正使用,下面这篇文章主要给大家介绍了关于vue项目中echarts自适应问题的高级解决过程,需要的朋友可以参考下
    2023-05-05
  • Vue3在Setup中使用axios请求获取的值方式

    Vue3在Setup中使用axios请求获取的值方式

    这篇文章主要介绍了Vue3在Setup中使用axios请求获取的值方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • 如何用 Deepseek 写的uniapp血型遗传查询工具

    如何用 Deepseek 写的uniapp血型遗传查询工具

    在现代社会中,了解血型遗传规律对于优生优育、医疗健康等方面都有重要意义,本文将介绍如何使用Uniapp开发一个跨平台的血型遗传查询工具,帮助用户预测孩子可能的血型,感兴趣的朋友一起看看吧
    2025-04-04
  • element 实现导航栏收起展开功能及思路

    element 实现导航栏收起展开功能及思路

    这篇文章主要介绍了element 实现导航栏收起展开功能,实现思路先给 el-menu加上 :collapse="isCollapse" 属性,这个属性也是 element 上的一个参数,意思为是否开启折叠动画,在 data 中定义 isCollapse ,用 true 和 false 控制展开与收起,需要的朋友可以参考下
    2023-01-01
  • Vue新搭档TypeScript快速入门实践记录

    Vue新搭档TypeScript快速入门实践记录

    TypeScript 是一种由微软开发的自由和开源的编程语言,它是 JavaScript 的一个超集,扩展了 JavaScript 的语法。这篇文章主要介绍了Vue新搭档TypeScript快速入门实践,需要的朋友可以参考下
    2021-06-06
  • Vue输入框实时验证IP地址合法性并在下方进行提示功能实现

    Vue输入框实时验证IP地址合法性并在下方进行提示功能实现

    在Vue组件中的IP地址输入框定义一个checkIpAddress方法,该方法使用正则表达式对传入的IP地址进行验证,这篇文章主要介绍了Vue输入框实时验证IP地址合法性并在下方进行提示,需要的朋友可以参考下
    2024-06-06
  • 教你利用Vue3模仿Windows窗口

    教你利用Vue3模仿Windows窗口

    最近学习了Vue3,利用vue3做了个好玩的项目,所以下面这篇文章主要给大家介绍了关于如何利用Vue3模仿Windows窗口的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04

最新评论