Vue3高效对接SSE数据流:实时更新不再难

461 阅读2分钟

🚀 Vue3高效对接SSE数据流:实时更新不再难

一、SSE技术简介

SSE(Server-Sent Events)是基于HTTP的单向通信协议,相比WebSocket更轻量,特别适合服务端主动推送数据的场景(如实时监控、股票行情等)。

核心优势:

自动重连机制

简单的文本协议

原生浏览器支持(除IE)

二、Vue3基础实现

  1. 创建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() }

  1. 组件内集成

三、进阶优化方案

  1. 自动重连增强版

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() }

  1. 性能优化技巧

使用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