uni-app 中 SSE 断连不自动重连,因非 H5 环境缺乏原生 EventSource 支持,需手动封装重连逻辑:小程序用 uni.request 模拟流式请求并心跳检测,App 端需监听前后台状态防冻结,重连策略应分级退避,且必须前后端协同处理 lastEventId 保证消息连续性。

uni-app 里 SSE 断开后不自动重连,不是你代码写错了,而是原生 EventSource 在多数非 H5 环境根本不存在或行为异常 —— 微信小程序没 EventSource,App 端 WebView 对长连接空闲超时极其敏感,H5 端虽有但不支持自定义请求头(比如 Authorization)。必须手动封装重连逻辑,不能依赖浏览器默认行为。
微信小程序端:用 uni.request 模拟 SSE + 主动心跳检测
小程序环境不支持 EventSource,也不能用 WebSocket 直接替代(协议不兼容),只能靠 uni.request 发起流式 GET 请求,并手动解析 text/event-stream 响应体。关键点在于:连接建立后,不能只等 success 回调,要持续监听响应流、识别 data: 行、处理换行分隔,并在无数据时主动判断超时。
- 服务端响应头必须包含
Content-Type: text/event-stream和Cache-Control: no-cache,否则小程序会缓存或截断响应 - 使用
uni.request的dataType: 'text',配合responseType: 'text'(HBuilderX 3.9+ 支持),避免二进制乱码 - 每次收到 chunk 后更新心跳时间戳;若超过 45s 无新数据,视为连接中断,立即
abort()当前请求并触发重连 - 重连前检查
uni.getNetworkType,网络为none时不重试,防止卡死
App 端(Android/iOS):避免 WebView 冻结导致静默断连
Android WebView 和 iOS WKWebView 在后台/切页时会冻结 JS 定时器,setTimeout 可能延迟数秒甚至失效,导致心跳失效、连接被代理或 CDN 强制关闭。不能只靠服务端心跳保活。
- 监听
plus.navigator.getState()或uni.onAppShow/uni.onAppHide,App 进入后台时主动abort()当前请求,恢复前台时重建连接 - 禁用 WebView 默认的空闲断连策略:Android 端需在
mainfest.xml中添加android:usesCleartextTraffic="true"(如用 HTTP);iOS 端需在Info.plist配置NSAppTransportSecurity允许明文请求(仅调试用) - 不要用
setInterval做心跳检测 —— 切页再回来可能堆积多个定时器,改用单次setTimeout+ 递归调用,每次重连前先clearTimeout - 服务端返回的每个 event 必须带
id:字段,客户端记录 lastEventId,重连时通过请求头Last-Event-ID携带上一次 ID,避免消息丢失
重连策略必须分级,不能无脑轮询
移动端网络抖动频繁,简单 setTimeout(() => connect(), 1000) 会导致大量无效请求,还可能被平台限流或服务端拒绝。
- 首次断连:立即重试(
delay = 0) - 连续失败 ≤3 次:固定间隔重试(如 1s)
- 失败 ≥4 次:指数退避(
1s → 2s → 4s → 8s),最大重试次数建议设为 5 - 重试期间若网络状态从
none变为wifi或4g,立刻清空退避计时器,重新从第 1 步开始 - 每次重连请求 URL 后拼上时间戳参数(如
?t=1730289360123),绕过某些代理的连接复用缓存
跨平台统一 API 封装时,onerror 和 onclose 不可靠
不同平台对错误事件的触发时机差异极大:H5 端可能触发 onerror,小程序压根不触发,App 端可能延迟数秒才回调。不能把重连逻辑绑死在这两个事件上。
- 所有平台都应基于「心跳超时」作为主判断依据,
onerror/onclose仅作辅助信号 - 封装类中维护一个
lastActiveTime时间戳,每次收到有效data:行就更新;另起一个checkAlive定时器每 5s 检查一次是否超时(比如 >45s) - 服务端推送的
ping:事件(内容为空或keepalive)也要计入lastActiveTime更新,否则纯业务数据间隔长就会误判断连 - 调试时在控制台打印
connectionStatus和lastActiveTime差值,比看onerror日志更早发现问题
最易被忽略的是 lastEventId 的传递和服务器的幂等处理 —— 客户端重连时带了 ID,服务端却没校验或没从断点续推,结果重复发、漏发、错序。这不在 uni-app 控制范围内,但必须前后端对齐逻辑,否则重连再稳也没用。











