56 lines
3.5 KiB
Markdown
56 lines
3.5 KiB
Markdown
# 切换对话诊断发现
|
||
|
||
## 当前已知
|
||
|
||
- 会话文件仍包含用户消息,暂未发现数据层删除。
|
||
- 切换通过 WebSocket `load_session` 请求完成,刷新会创建新连接。
|
||
- 服务端日志存在大量心跳终止和断线重连记录。
|
||
- 前端同时处理会话缓存、加载请求代次、历史分页、运行态恢复和滚动位置。
|
||
|
||
## 可复核证据
|
||
|
||
- `server.js:5656-5658` 普通加载只发送最近 `INITIAL_HISTORY_COUNT = 12` 条;
|
||
`server.js:10890-10907` 同时发送完整 `historyTotal`、`historyCursor`、
|
||
`historyBaseIndex` 和 `historyTruncated`,普通大历史请求可以出现
|
||
`messages=12, historyTotal=99, historyCursor=87, historyPending=false`。
|
||
- 原逻辑 `public/app.js:2607-2611` 用 `!payload.historyPending` 推导
|
||
`complete`,因此上述部分快照会被标成完整;随后
|
||
`session_info → cacheSessionSnapshot → getSessionCacheDisposition →
|
||
showCachedSession` 可在 A → B → A 时绕过服务端重新加载。
|
||
- 修复后 `normalizeSessionSnapshot` 和 `isCompleteSessionSnapshot` 共同要求
|
||
游标归零、未截断、未等待分片且缓冲数覆盖总数;缓存写入和读取都复用同一
|
||
谓词。历史分片按 `historyBaseIndex` 合并,最后一页才转换为完整缓存。
|
||
- 部分快照现在进入独立 `sessionHistoryBuffers`,仅供后续 `load_history_page`
|
||
合并;`getSessionCacheDisposition` 永远不会把它当作可展示缓存。分页游标归
|
||
零后才调用 `cacheSessionSnapshot`,因此 A → B → A 不会复用半截历史。
|
||
- `logs/process.log` 中存在 `ws_heartbeat_terminate`,例如
|
||
`2026-09-13T07:30:03.445Z`,`missedPongs=4`、`lastActivityAgeMs=150471`;
|
||
`server.js:2216-2221` 的 `markWsActivity` 已会把 `isAlive` 恢复为 `true`,
|
||
因此该记录更符合浏览器/反向代理长期未返回 pong 的半断连接,而不是服务端
|
||
漏置位。
|
||
- 客户端原先只在 `onclose` 触发重连;现增加 `WS_CLIENT_HEARTBEAT_INTERVAL_MS`
|
||
(15 秒)与 `WS_CLIENT_HEARTBEAT_TIMEOUT_MS`(10 秒),通过
|
||
`client_heartbeat → client_heartbeat_ack` 主动识别浏览器仍显示 `OPEN` 的半断,
|
||
再复用现有 `onclose` 流程重放切换请求。
|
||
|
||
## 问题边界
|
||
|
||
- 会话文件未发现消息被删除;气泡消失的直接原因是前端错误缓存/重绘,
|
||
不是数据库或服务端历史丢失。
|
||
- WebSocket 处于浏览器 `OPEN` 但链路半断时,`send(load_session)` 可能无效;
|
||
刷新页面会强制新建连接。现在客户端最多约 25 秒主动发现并重连,真实反向
|
||
代理是否丢弃控制帧仍需浏览器现场或代理配置验证。
|
||
- 未重启现有 `ccweb`,因为当前会话列表中还有另一个 running 对话;源码修复
|
||
需在安全窗口重启后才会进入线上进程。
|
||
|
||
## 2026-09-13 新增线上证据
|
||
|
||
- 用户截图中的 `Unknown type: client_heartbeat` 证实线上 PM2 仍运行未包含
|
||
`client_heartbeat` 分支的旧 `server.js`;前端先部署心跳会被旧服务端当作业务
|
||
错误,并触发连接重连循环。
|
||
- `mcp__ccweb__ccweb_list_conversations(status=running)` 显示当前会话之外仍有
|
||
一个 running 会话,按项目运维约定本轮不能重启 PM2。
|
||
- 已在前端加入 `auth_result.features.clientHeartbeat` 能力闸门:旧服务端不声明
|
||
时不发送心跳;即使旧页面已发送并收到 Unknown type,也会静默停用心跳,不再
|
||
将协议探测错误显示到聊天区。新版服务端已声明该能力,安全重启后可恢复探测。
|