TL;DR: WebSocket 和 TanStack Query 通过一个简单的模式协同工作:挂载时订阅 WebSocket 事件,将更新推入查询缓存,由 Query 处理协调。本指南涵盖通过 WebSocket 事件更新缓存查询、实时数据与轮询数据的去重、重连策略,以及自定义
useWebSocketQueryhook。
Introduction
实时数据已成为现代 SaaS 应用的基础功能——协作文档编辑、实时仪表盘、通知徽章、聊天等场景都离不开它。TanStack Query 优雅地处理服务端状态缓存,但 WebSocket 引入的事件需要绕过正常的请求生命周期。
核心思路:WebSocket 消息应直接更新查询缓存,而不是触发重新获取。这样可以获得即时更新,只触及发生变化的那部分数据。
WebSocket 订阅 Hook
function useWebSocketSubscription<TData>(
channel: string,
onMessage: (data: TData) => void
) {
useEffect(() => {
const ws = new WebSocket(`wss://api.tanstackship.com/ws?channel=${channel}`)
ws.onmessage = (event) => {
const data = JSON.parse(event.data) as TData
onMessage(data)
}
ws.onclose = () => {
// 3 秒后重连
setTimeout(() => {
new WebSocket(`wss://api.tanstackship.com/ws?channel=${channel}`)
}, 3000)
}
return () => ws.close()
}, [channel, onMessage])
}
该订阅 hook 负责管理 WebSocket 的完整生命周期——连接、消息处理,以及关闭后的自动重连。关于离线期间持久化数据和重连后同步的策略,参见 TanStack Query 离线支持。
与 Query Cache 集成
TanStack Query 的缓存是服务端状态的中心枢纽。当 WebSocket 事件到达时,通过 queryClient.setQueryData 直接更新缓存,避免不必要的网络请求。关于乐观更新和缓存垃圾回收等高级模式,参见 TanStack Query 缓存失效策略。
function useRealtimeDashboard() {
const queryClient = useQueryClient()
const { data } = useQuery({
queryKey: ['dashboard', 'metrics'],
queryFn: fetchDashboardMetrics,
refetchInterval: 60_000, // 降级轮询
})
useWebSocketSubscription('dashboard:metrics', (metric) => {
queryClient.setQueryData(['dashboard', 'metrics'], (old: any) => {
if (!old) return old
return {
...old,
activeUsers: metric.activeUsers,
recentSignups: old.recentSignups + (metric.newSignup ? 1 : 0),
}
})
})
return data
}
该模式通过 WebSocket 事件保持仪表盘数据实时更新,同时维持 60 秒的轮询降级方案。关于补充此实时方案的缓存策略,参见 边缘缓存策略指南。
实时策略对比
| 策略 | 延迟 | 服务端成本 | 复杂度 | 适用场景 |
|---|---|---|---|---|
| WebSocket + 缓存更新 | 即时 | 高 | 中等 | 实时仪表盘、聊天 |
| Server-Sent Events | <1s | 中 | 低 | 单向数据流 |
| 短轮询 (3s) | 3-10s | 低 | 极简 | 非关键更新 |
| 长轮询 | 1-5s | 中 | 中等 | 仅作降级方案 |
| TanStack Query refetchInterval | 可配置 | 低 | 极简 | 后台同步 |
Conclusion
WebSocket + TanStack Query 构成了强大的实时架构,缓存作为唯一真实数据源。WebSocket 事件直接更新缓存,而 TanStack Query 自动处理轮询降级、重试逻辑和缓存一致性。在生产环境部署时,结合 SaaS 监控与可观测性 来追踪 WebSocket 健康状态和缓存性能。