vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue3 SSE实现前端全局事件通讯

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

作者:你的眼睛會笑

文章介绍了使用Vue3和VueUse实现基于SSE(Server-Sent Events)的全局事件通讯系统,SSE具有单向通信、基于HTTP、自动重连和轻量级等特点,适合实时性要求高的应用,实现方案包括订阅消息、取消订阅和关闭连接等功能

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

什么是SSE (useEventSource)

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

为什么选择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连接,可以实现跨组件的实时通讯,减少重复连接,提高应用性能。

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

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

您可能感兴趣的文章:
阅读全文