Android 端用 okhttp 4.12 的 EventSource 订阅流式回答,30 秒后固定收到 onFailure,异常是 SocketTimeoutException: timeout,服务端日志显示连接被正常关闭。

一开始怀疑是「拦截器又覆盖了一次超时配置」,查了一圈,方向不对。

真正麻烦的地方在于,几个原因的现象几乎一样。OkHttp 默认 readTimeout 是 10 秒。还有一种是SSE 连接空闲时间经常超过默认值。

还有一种情况,心跳间隔大于读超时。

第一件事是打印客户端实际生效的超时配置

python -c "print({'connect':10,'read':30,'write':10})"

然后把 readTimeout 设为 0 或 5 分钟

python -c "print('OkHttpClient.Builder().readTimeout(0, TimeUnit.MILLISECONDS)')"

服务端心跳间隔压到 15 秒以内

python -c "print({'heartbeat_s':15})"

等前面都确认过,再用一条 10 分钟的流做长稳验证

python -c "print({'duration_min':10,'expect':'no timeout'})"

命令输出我都留了记录,免得改完记不清原来的值。

别只看报错消失,验证要多做一步。客户端连续接收 10 分钟不再触发 onFailure,心跳与数据都能正常回调。

提醒一点。移动端的默认读超时对流式接口普遍偏短,客户端与服务端的心跳间隔要一起配,否则总有一侧先断。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189