🚀 Vue3高效对接SSE数据流:实时更新不再难
一、SSE技术简介
SSE(Server-Sent Events)是基于HTTP的单向通信协议,相比WebSocket更轻量,特别适合服务端主动推送数据的场景(如实时监控、股票行情等)。
核心优势:
自动重连机制
简单的文本协议
原生浏览器支持(除IE)
二、Vue3基础实现
- 创建EventSource连接
// utils/sse.js export const useSSE = (url, callback) => { const eventSource = new EventSource(url)
eventSource.onmessage = (event) => { callback(JSON.parse(event.data)) }
eventSource.onerror = () => { eventSource.close() }
return () => eventSource.close() }
- 组件内集成
三、进阶优化方案
- 自动重连增强版
const createSSEConnection = (url, callback) => { let retryCount = 0 const maxRetries = 5
const connect = () => { const es = new EventSource(url)
es.onmessage = (e) => {
retryCount = 0 // 重置重连计数器
callback(e.data)
}
es.onerror = () => {
es.close()
if (retryCount++ < maxRetries) {
setTimeout(connect, 1000 * Math.min(retryCount, 4))
}
}
return es
}
return connect() }
- 性能优化技巧
使用EventSource的last-event-id实现断点续传
对高频数据采用防抖处理
复杂数据场景考虑使用Web Workers
四、实际应用场景
示例代码
export class SSEService {
constructor(url) {
this.url = url
this.eventSource = null
this.listeners = new Map()
}
connect() {
this.eventSource = new EventSource(this.url)
this.eventSource.onmessage = (event) => {
this.dispatch('message', event.data)
}
this.eventSource.addEventListener('custom-event', (e) => {
this.dispatch('custom', e.data)
})
this.eventSource.onerror = (error) => {
this.dispatch('error', error)
}
}
on(event, callback) {
if (!this.listeners.has(event)) {
this.listeners.set(event, new Set())
}
this.listeners.get(event).add(callback)
}
dispatch(event, data) {
const callbacks = this.listeners.get(event)
callbacks?.forEach(cb => cb(data))
}
close() {
this.eventSource?.close()
}
}
// 使用示例:
// const service = new SSEService('/stream')
// service.on('message', data => console.log(data))
// service.connect()
export class SSEService {
constructor(url) {
this.url = url
this.eventSource = null
this.listeners = new Map()
}
connect() {
this.eventSource = new EventSource(this.url)
this.eventSource.onmessage = (event) => {
this.dispatch('message', event.data)
}
this.eventSource.addEventListener('custom-event', (e) => {
this.dispatch('custom', e.data)
})
this.eventSource.onerror = (error) => {
this.dispatch('error', error)
}
}
on(event, callback) {
if (!this.listeners.has(event)) {
this.listeners.set(event, new Set())
}
this.listeners.get(event).add(callback)
}
dispatch(event, data) {
const callbacks = this.listeners.get(event)
callbacks?.forEach(cb => cb(data))
}
close() {
this.eventSource?.close()
}
}
// 使用示例:
// const service = new SSEService('/stream')
// service.on('message', data => console.log(data))
// service.connect()
实时仪表盘:每3秒更新一次指标数据
聊天应用:显示新消息通知
日志监控:实时显示服务器日志
常见问题排查
❌ 跨域问题:确保服务端设置Access-Control-Allow-Origin❌ 连接中断:检查服务端是否保持连接打开 ❌ 数据解析错误:验证服务端发送的是标准SSE格式
提示:对于需要双向通信的场景,建议改用WebSocket