Skip to content

实时通信

项目使用 SSE(Server-Sent Events)实现服务端向客户端的实时推送。

基本用法

typescript
import { useSse } from "@/composables/useSse"

const { isConnected, connect, disconnect, on } = useSse()

// 建立连接
connect()

// 订阅事件
const unsubscribe = on('dict', (data) => {
  console.log('字典变更:', data)
})

// 断开连接
disconnect()

连接状态

typescript
const { connectionState, isConnected } = useSse()

// connectionState 可能的值:
// DISCONNECTED - 未连接
// CONNECTING   - 连接中
// CONNECTED    - 已连接

事件订阅

SSE 支持订阅多个命名事件:

typescript
// 订阅字典变更事件
on('dict', (data) => {
  // data = { dictCode: string, timestamp: number }
})

// 订阅在线人数事件
on('online-count', (count) => {
  // count = number
})

// 订阅默认 message 事件
on('message', (data) => {
  console.log('收到消息:', data)
})

on() 返回取消订阅函数,组件卸载时应调用:

typescript
const unsubscribe = on('dict', handler)

onUnmounted(() => {
  unsubscribe()
})

配置选项

typescript
const { connect } = useSse({
  url: '/api/v1/sse/connect',  // SSE 连接地址,默认走 VITE_APP_BASE_API 代理
  debug: true,                   // 开启调试日志
  connectionTimeout: 10000,      // 连接超时 10s
  reconnectInterval: 5000,       // 首次重连等 5s
  maxReconnectInterval: 120000, // 重连间隔最大 2min
  maxReconnectAttempts: 10,      // 最多重试 10 次
})

自动重连

SSE 内置指数退避重连策略:

  • 首次重连等待 reconnectInterval(默认 5s)
  • 每次失败间隔翻倍,最大不超过 maxReconnectInterval
  • 超过 maxReconnectAttempts 后停止重连
  • 主动调用 disconnect() 不会触发重连

鉴权机制

SSE 连接通过 URL 参数传递 token(EventSource 不支持自定义 Header):

/api/v1/sse/connect?accessToken=xxx

未登录时自动跳过连接,无需手动判断。

资源清理

登出时调用 cleanupSse() 释放所有资源:

typescript
import { cleanupSse } from "@/composables/useSse"

// 登出时
cleanupSse()

与 WebSocket 的区别

特性SSEWebSocket
通信方向服务端 → 客户端双向
协议HTTPWS
重连自动需手动实现
兼容性H5 + 小程序需适配小程序
适用场景推送通知、状态同步聊天、实时协作

SSE 适用于服务端主动推送的场景(字典同步、在线人数等),如需双向通信再考虑 WebSocket。

基于 MIT 许可发布 · 由 ❤️ 和 ☕ 驱动 · 支持作者