概览SSE 适合一对多的服务端到客户端单向推送场景。Next.js 15 在 App Router 下以 Route Handler 配合 Edge Runtime 的 Web Streams 能稳定输出 `text/event-stream`。客户端以 `EventSource` 监听消息,实现增量且低延迟的 UI 更新。与 Cache Tags 协同可在写操作后触发局部失效,保证近实时一致性。服务端实现app/api/sse/route.tsexport const runtime = 'edge' function encode(data: unknown) { return `data: ${JSON.stringify(data)}\n\n` } export async function GET() { const stream = new ReadableStream({ start(controller) { controller.enqueue(new TextEncoder().encode(encode({ type: 'init', ts: Date.now() }))) let i = 0 const timer = setInterval(() => { i++ controller.enqueue(new TextEncoder().encode(encode({ type: 'tick', i, ts: Date.now() }))) }, 2000) const heartbeat = setInterval(() => { controller.enqueue(new TextEncoder().encode(':\n\n')) }, 15000) const stop = () => { clearInterval(timer) clearInterval(heartbeat) controller.close() } ;(globalThis as any).addEventListener?.('sse-stop', stop) }, }) return new Response(stream, { headers: { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive', }, }) } 客户端订阅const es = new EventSource('/api/sse') es.onmessage = (e) => { const payload = JSON.parse(e.data) if (payload.type === 'tick') { const el = document.getElementById('tick') if (el) el.textContent = String(payload.i) } } es.onerror = () => { es.close() } 与 Cache Tags 协同在写操作完成后触发对应标签失效,并通知客户端执行轻量刷新或局部重取。import { revalidateTag } from 'next/cache' export async function POST(req: Request) { const body = await req.json() const ok = await save(body) if (ok) { revalidateTag('feed') } return Response.json({ ok }) } async function save(v: unknown) { return true } 增量更新治理使用心跳帧保持连接活性并帮助中间件区分空闲与断线。严格设置 `Cache-Control: no-cache` 以避免中间层缓存截断流。客户端本地维护最后序列号或时间戳,断线后从断点继续。对于高频主题,SSE 与轮询结合以兜底,避免浏览器连接上限影响。指标与验证浏览器:Chrome 120+、Safari 17+、Firefox 120+Next.js:15.0+;Node.js:20.x;Edge Runtime:稳定延迟:首包通常在 200ms 以内;连接存活超过 30 分钟在触发 `revalidateTag('feed')` 后客户端 2–5s 内完成轻量刷新可访问性与稳定性对断线重连增加退避策略,避免服务端压力尖峰。UI 更新遵循无障碍规范,重要信息使用 ARIA live region 提示。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部
1.620238s