Bug Report: Agent 运行时前端反复断开重连(ping timeout)
描述
在使用 Agent 进行小说创作协作时,前端(Electron 桌面版)频繁出现"断开连接 → 自动重连",严重干扰写作流程。连接日志显示断连原因为 ping timeout。
环境
- OpenFic 版本:0.10.2(桌面版)
- 操作系统:Windows
- 模型:自定义 OpenAI 兼容 provider(CommandCode 的
deepseek/deepseek-v4-flash)
- 项目规模:百万字级别长篇小说(大量章节、设定、角色)
复现步骤
- 打开一个较大的项目
- 在 Agent 会话中发送消息,触发 Agent 运行(同时可能有后台章节摘要任务在跑)
- 观察连接状态:频繁显示断开并自动重连
日志证据(runtime/logs/connect.log)
[2026-08-26T11:53:19.487Z] socket event=disconnected url=http://127.0.0.1:52940 transport=websocket active=true message=ping timeout
[2026-08-26T11:53:20.070Z] socket event=reconnect-attempt url=http://127.0.0.1:52940 transport=websocket attempt=1
[2026-08-26T11:53:40.073Z] socket event=connect-error url=http://127.0.0.1:52940 transport=websocket active=true message=timeout
[2026-08-26T11:53:41.826Z] socket event=reconnect-attempt url=http://127.0.0.1:52940 transport=websocket attempt=2
[2026-08-26T12:00:51.918Z] socket event=disconnected url=http://127.0.0.1:52940 transport=websocket active=true message=ping timeout
[2026-08-26T12:04:32.122Z] socket event=disconnected url=http://127.0.0.1:57375 transport=websocket active=true message=ping timeout
断连后重连也出现 connect-error timeout,说明后端在断连期间完全无响应(连新连接都无法建立),持续数分钟。
根因分析(源码定位)
1. Socket.IO 心跳超时配置偏紧 — backend/app/socket/server.py:
sio = socketio.AsyncServer(
async_mode="asgi",
ping_interval=25, # 25 秒一次心跳
ping_timeout=20, # 20 秒无响应即判定断连
)
当后端事件循环被大任务短暂阻塞超过 20 秒时,前端即判定 ping timeout 并断连。
2. 后台 worker 与 WebSocket 服务器共用同一事件循环 — backend/app/background/runtime/supervisor.py:
worker = BackgroundWorker(...)
self._worker_tasks.append(asyncio.create_task(worker.run())) # 同一 asyncio 事件循环
后台任务(章节摘要批量生成、检索索引、上下文压缩)与 Socket.IO 心跳处理运行在同一个 asyncio 事件循环。百万字项目的摘要批次任务会持续长时间运行(日志显示每 30-60 秒一个章节摘要),期间任何同步阻塞(LLM 流式响应、大 SQLite 事务、向量索引)都会饿死心跳处理,导致 ping 超时。
3. 断连期间重连也失败:主事件循环被占满时,新的 WebSocket 连接也无法被接受(日志 connect-error timeout),放大为"断连后长时间连不上"。
影响
- Agent 协作创作时频繁断连重连,打断写作流程
- 重连期间可能丢失部分实时事件(Agent 进度、工具结果)
- 大项目 + 自动摘要场景下问题尤其严重
建议修复
- 调大心跳超时:
ping_interval=60, ping_timeout=60 或更高,容忍正常的后台任务阻塞
- 后台 worker 与主事件循环隔离:将 BackgroundWorker 放到独立进程(ZMQ transport 已经支持跨进程,
background_zmq_job_endpoint 目前是 inproc://,可考虑改为真正的进程间通道),或用 asyncio.to_thread 包装同步阻塞操作
- 断连后快速恢复:确保新连接在事件循环繁忙时也能被优先接受
临时规避(供其他用户参考)
- 将
server.py 的 ping_timeout 调大到 60 秒可显著缓解(已验证有效)
- Agent 使用时暂停自动章节摘要任务可减少事件循环压力
Bug Report: Agent 运行时前端反复断开重连(ping timeout)
描述
在使用 Agent 进行小说创作协作时,前端(Electron 桌面版)频繁出现"断开连接 → 自动重连",严重干扰写作流程。连接日志显示断连原因为
ping timeout。环境
deepseek/deepseek-v4-flash)复现步骤
日志证据(
runtime/logs/connect.log)断连后重连也出现
connect-error timeout,说明后端在断连期间完全无响应(连新连接都无法建立),持续数分钟。根因分析(源码定位)
1. Socket.IO 心跳超时配置偏紧 —
backend/app/socket/server.py:当后端事件循环被大任务短暂阻塞超过 20 秒时,前端即判定
ping timeout并断连。2. 后台 worker 与 WebSocket 服务器共用同一事件循环 —
backend/app/background/runtime/supervisor.py:后台任务(章节摘要批量生成、检索索引、上下文压缩)与 Socket.IO 心跳处理运行在同一个 asyncio 事件循环。百万字项目的摘要批次任务会持续长时间运行(日志显示每 30-60 秒一个章节摘要),期间任何同步阻塞(LLM 流式响应、大 SQLite 事务、向量索引)都会饿死心跳处理,导致 ping 超时。
3. 断连期间重连也失败:主事件循环被占满时,新的 WebSocket 连接也无法被接受(日志
connect-error timeout),放大为"断连后长时间连不上"。影响
建议修复
ping_interval=60, ping_timeout=60或更高,容忍正常的后台任务阻塞background_zmq_job_endpoint目前是inproc://,可考虑改为真正的进程间通道),或用asyncio.to_thread包装同步阻塞操作临时规避(供其他用户参考)
server.py的ping_timeout调大到 60 秒可显著缓解(已验证有效)