vue3使用SSE实现前端全局事件通讯方式
作者:你的眼睛會笑
文章介绍了使用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); } } }); };
核心功能实现
- 订阅消息
// 添加消息监听 export function addListener(callback: (data: any) => void) { callbacks.add(callback); return () => removeListener(callback); // 返回取消订阅函数 }
- 取消订阅
// 移除消息监听 function removeListener(callback: (data: any) => void) { callbacks.delete(callback); }
- 关闭连接
// 关闭SSE连接 export function closeSse() { eventSource?.close(); eventSource = null; callbacks.clear(); }
在Vue组件中使用
- 初始化连接
// 在应用初始化时调用 import { initSSE } from '@/utils/sse'; // 启动SSE连接 initSSE();
- 订阅消息
import { addListener,closeSse } from '@/utils/sse'; // 组件内订阅 const unsubscribe = addListener((data) => { console.log('收到消息:', data); // 处理业务逻辑... }); // 组件销毁时取消订阅 onUnmounted(() => { closeSse(); });
实际应用场景
- 实时通知系统 :新消息提醒、系统公告等
- 数据监控 :实时展示服务器状态、监控数据
- 协同编辑 :多人协作时的内容同步
- 任务进度更新 :长时间任务的进度通知
性能优化建议
- 心跳机制 :服务器定期发送心跳包保持连接
- 消息压缩 :对大消息进行压缩处理
- 批量发送 :合并多个小消息为一次发送
- 连接共享 :多个组件复用同一个连接
完整代码
// 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轮询作为补充。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。