实时通信
项目使用 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 的区别
| 特性 | SSE | WebSocket |
|---|---|---|
| 通信方向 | 服务端 → 客户端 | 双向 |
| 协议 | HTTP | WS |
| 重连 | 自动 | 需手动实现 |
| 兼容性 | H5 + 小程序 | 需适配小程序 |
| 适用场景 | 推送通知、状态同步 | 聊天、实时协作 |
SSE 适用于服务端主动推送的场景(字典同步、在线人数等),如需双向通信再考虑 WebSocket。
