单页应用路由切换时必须显式关闭sse连接,否则旧实例持续保活、占用资源并引发泄漏;需在组件卸载时调用close()、移除监听器、通知服务端终止推送,并清理定时器与强引用。

在单页应用中切换页面时,SSE 连接不会自动销毁,必须主动关闭,否则旧连接持续保活、接收数据、占用内存和带宽,还可能引发监听器泄漏或服务端资源堆积。
路由离开时显式调用 close()
不能依赖浏览器自动回收,必须在组件卸载阶段触发关闭逻辑:
- React 中,在 useEffect 清理函数 里执行
eventSource?.close() - Vue 3 使用 onBeforeUnmount;Vue 2 对应 beforeDestroy
- 若使用全局路由守卫(如 Vue Router 的
beforeEach),可结合当前 SSE 实例的路由标识(如es.__route = '/notify')精准关闭对应连接
避免监听器残留与重复创建
频繁切换页面易导致多个 EventSource 实例共存,旧实例未关闭就继续监听:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 禁止将 EventSource 声明在模块顶层或全局作用域,防止跨路由意外复用
- 绑定事件监听器时,使用命名函数或保存引用:
const onMsg = e => {...}; source.addEventListener('message', onMsg),关闭前再调用removeEventListener('message', onMsg) - 清除直接赋值的回调:
source.onerror = null; source.onopen = null
服务端同步终止推送流
客户端关了,服务端若不知情,仍可能向已断开的连接写入数据,造成句柄泄漏或内存堆积:
- 服务端需监听响应流的
'close'或'end'事件(Node.js 中为res.socket.on('close')),感知断连后立即清理上游任务 - 客户端关闭前,可发起轻量终结请求(如
POST /api/sse/end?sid=xxx),服务端据此清空会话缓存与推送队列 - 为每个 SSE 请求添加唯一标识头(如
X-Session-ID),便于服务端精准识别并终止对应流
关闭后重置状态与清理副作用
仅调用 close() 不够,还需解除所有强引用和定时任务:
- 将连接状态标志(如
this.isSSEActive = false)置为 false,后续逻辑均先校验该标志 - 清除关联的 UI 定时器(如心跳检测、倒计时):
clearTimeout(this.pingTimer) - 解绑全局事件(如
window.removeEventListener('beforeunload', ...)) - 清空待处理消息队列、取消 pending Promise、重置本地缓存状态
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










