Desktop Staging 聊天卡「排队中」:WS 升级头与 Origin 排查
桌面端发聊天后 UI 一直显示排队、Agent 实际已回复。根因:nginx 丢 WebSocket 升级头(400)+ Go Origin 白名单不含 localhost:5173(403)。
by 于尘
·
记录日期:2026-06-04
1. 问题背景
用 pnpm dev:desktop:staging 连远程 jiulou.yuchengji.com,在聊天窗口给总理 Agent 发问候后,界面一直显示「排队中」。手动中止后拉取消息,发现 Agent 其实早已回复。
本地 Desktop 终端全程只有 [ws] disconnected, reconnecting in 3s,从未出现 [ws] connected。HTTP API(登录、发消息、取消任务)均 200。
2. 问题列表
2.1 聊天 UI 卡在「排队中」,服务端任务已完成
现象
- 发消息后 StatusPill 停在
queued - 中止任务后
GET .../messages能看到 assistant 回复 - 终端无
task:dispatch/chat:done等 WS 相关日志
根因(链式,证据级)
| 层级 | 为什么 | 证据 |
|---|---|---|
| why1 | UI 一直显示排队 | chat-window.tsx 乐观写入 status: "queued",靠 WS 推进状态 |
| why2 | pending task 未更新 | use-realtime-sync.ts 监听 task:dispatch、chat:done 等,均走 WebSocket |
| why3 | WS 从未稳定连接 | 日志只有 disconnected,无 connected |
| why4a | nginx 未正确转发 WS 升级头 | 抓包:backend 收到 connection: close,无 Upgrade;Go 报 upgrade token not found → 400 |
| why4b | (修完 nginx 后)dev Origin 被拒 | Origin: http://localhost:5173 → 403;日志 ws: rejected origin;CORS_ALLOWED_ORIGINS 为空时仅允许 FRONTEND_ORIGIN |
方案
| 内容 | 优点 | 缺点 | |
|---|---|---|---|
| 短期 A | nginx:map $http_upgrade + location /ws 使用 Connection $connection_upgrade |
一次修好生产/浏览器 WS | 需 reload nginx |
| 短期 B | backend:CORS_ALLOWED_ORIGINS 增加 http://localhost:5173,5174 |
Desktop dev 可连远程 WS | 扩大 WS Origin 白名单,仅 dev 需要 |
| 长远 | 反代模板入库 / 部署检查清单含 WS 握手自检 | 新环境不易再犯 | 要维护文档与脚本 |
采纳方案
- 已在
nginx.conf增加map,/ws使用$connection_upgrade(见docs/assets/秘密文档/nginx配置.md)。 - 已设置
CORS_ALLOWED_ORIGINS=https://jiulou.yuchengji.com,http://localhost:5173,http://localhost:5174并重启 backend。
修复后验证(2026-06-05,SSH + 本地握手)
| 检查项 | 结果 |
|---|---|
CORS_ALLOWED_ORIGINS 含 localhost:5173 |
✅ |
wss://.../ws + Origin: https://jiulou.yuchengji.com |
✅ 返回 {"error":"invalid token"}(upgrade 通) |
同上 + Origin: http://localhost:5173 |
✅ 同上(修前为 403) |
本地 Desktop 应出现 [ws] connected;再发聊天应能从「排队」进入「思考中」并自动展示回复。
补充用例
- 浏览器打开
https://jiulou.yuchengji.com:issue/inbox 实时刷新是否正常 pnpm dev:desktop:staging:发聊天 → 不中止 → 观察 pill 与消息是否自动更新- 若仍断线:查
docker logs jiulou-backend-1 | grep -i origin与 nginxaccess.log中/ws状态码
相关文档
- 启动与 Origin 说明:
20260604-启动脚本.md - 线上 nginx 全文备份:
docs/assets/秘密文档/nginx配置.md
3. 小结
不是 Agent 没跑,也不是聊天业务逻辑 bug,而是 WebSocket 没连上,UI 收不到任务生命周期事件。根因分两段:nginx 丢升级头(400)→ 修 map 与 Connection;Go Origin 白名单不含 localhost:5173(403)→ 补 CORS_ALLOWED_ORIGINS。HTTP 正常而「实时不动」时,优先查 WS 日志与 [ws] connected。