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:dispatchchat: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 originCORS_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 握手自检 新环境不易再犯 要维护文档与脚本

采纳方案

  1. 已在 nginx.conf 增加 map/ws 使用 $connection_upgrade(见 docs/assets/秘密文档/nginx配置.md)。
  2. 已设置 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 与 nginx access.log/ws 状态码

相关文档

  • 启动与 Origin 说明:20260604-启动脚本.md
  • 线上 nginx 全文备份:docs/assets/秘密文档/nginx配置.md

3. 小结

不是 Agent 没跑,也不是聊天业务逻辑 bug,而是 WebSocket 没连上,UI 收不到任务生命周期事件。根因分两段:nginx 丢升级头(400)→ 修 map 与 ConnectionGo Origin 白名单不含 localhost:5173(403)→ 补 CORS_ALLOWED_ORIGINS。HTTP 正常而「实时不动」时,优先查 WS 日志与 [ws] connected

← 所有文章