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轮询作为补充。

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

相关文章

  • Vue中添加手机验证码组件功能操作方法

    Vue中添加手机验证码组件功能操作方法

    组件是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。这篇文章主要介绍了VUE 中添加手机验证码组件,需要的朋友可以参考下
    2017-12-12
  • vue的Element组件上传文件el-upload上传成功后清空方式

    vue的Element组件上传文件el-upload上传成功后清空方式

    文章介绍了几种清空文件上传组件的方法,包括设置file-list为空数组和修改组件key,这些方法可以帮助在新增或修改时清空组件内容,解决实际开发中的问题
    2026-02-02
  • Vue实现二维码的展示及下载功能

    Vue实现二维码的展示及下载功能

    这篇文章主要介绍了Vue实现二维码的展示及下载功能,其中downloadQRCode()函数中的url为要下载的文件的路径,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • Vue实现手机扫描二维码预览页面效果

    Vue实现手机扫描二维码预览页面效果

    这篇文章主要为大家详细介绍了Vue实现手机扫描二维码预览页面效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • Vue权限指令控制权限详解

    Vue权限指令控制权限详解

    因为项目中需要根据后端返回的权限进行功能的显示隐藏,所以就加了个权限指令。不用写if else进行判断,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09
  • Vue2.x中利用@font-size引入字体图标报错的解决方法

    Vue2.x中利用@font-size引入字体图标报错的解决方法

    今天小编就为大家分享一篇Vue2.x中利用@font-size引入字体图标报错的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • Vue3如何实现超丝滑打字机效果组件(可复用、高定制)

    Vue3如何实现超丝滑打字机效果组件(可复用、高定制)

    最近遇到一个需求就是使用Web网页实现打字机特效,觉着还不错,这篇文章主要介绍了Vue3如何实现超丝滑打字机效果组件的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2026-03-03
  • 解读计算属性和watch监听的区别及说明

    解读计算属性和watch监听的区别及说明

    计算属性是基于它们的依赖进行缓存的,只有在它的相关依赖发生改变时才会重新求值,而watch则是一个更为通用的监听器,它可以在数据变化时执行异步操作或开销较大的操作
    2025-01-01
  • vue中解决跨域的常见方案分享(建议收藏)

    vue中解决跨域的常见方案分享(建议收藏)

    本文主要介绍了前后端分离项目中的跨域问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-11-11
  • 对vux点击事件的优化详解

    对vux点击事件的优化详解

    今天小编就为大家分享一篇对vux点击事件的优化详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08

最新评论