Guanghu Domestic Migration a27e87cb99 chore: import sanitized domestic snapshot for REPO-007
Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc

[SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
2026-07-17 15:59:55 +08:00

5.8 KiB
Raw Blame History

GHCS v0.2 终端排障 SOPSSH Web Terminal Debug SOP


1本次问题的具体原因复盘结论

1.1 真正卡住不是一个 bug而是三层叠加

  1. 页面 200 ≠ 终端可用
  • /console/terminal 返回 200 只说明 Next 页面渲染成功。
  • 终端真正依赖:GET /ws/terminal/servers + WS /ws/terminal/{server_key}
  • 只要后端路由未挂载、或前端没打到正确后端,页面仍 200但终端必失败。
  1. 环境变量未生效 / localhost 解析导致“像玄学”
  • NEXT_PUBLIC_CONSOLE_API 改了但未重启前端 → Next 继续用旧值。
  • localhost 在部分环境可能走 IPv6::1)而后端仅在 IPv4127.0.0.1)监听 → 表现为偶发连不上 / 重试。
  1. 焦点判断误区:光标渲染 ≠ 键盘输入通道
  • xterm 光标是渲染状态,点别处后仍可能停在原位。
  • 真正需要判断的是:键盘输入是否进入终端(用 echo 回显验证)。

1.2 之前陷入的误区(导致一直修不动)

  • 误区 A把“页面能打开”当成“后端都通了”
  • 误区 B用光标/感觉判断焦点,而不是用命令回显判定输入通道
  • 误区 C.env.local 不重启前端,导致“我明明改了但没变化”
  • 误区 D一次改太多前端/后端/依赖/配置一起动),失去最小证据链

1.3 本次为什么修得顺利(方法)

把问题拆成 4 层,并且每层只用一个“最小证据”验收:

  • 后端活着:/docs 能开
  • 路由挂载:curl -i /ws/terminal/servers 看 200/404
  • 前端指向正确后端:.env.local + 重启
  • 交互与焦点:whoami / pwd / echo ... 回显

2GHCS v0.2 终端排障 SOP五段式不跳步

Step 0准备两窗口

  • 终端 AbackendFastAPI
  • 终端 BfrontendNext.js

Step 1确认后端在跑

cd ~/guanghu-dev/ghcs-mono/backend
source venv/bin/activate
python -m uvicorn main:app --host 127.0.0.1 --port 5002 --reload

验收:浏览器打开 http://127.0.0.1:5002/docs


Step 2确认 terminal_router 已挂载(最关键一锤)

curl -i http://127.0.0.1:5002/ws/terminal/servers
  • 200 + JSON:后端终端路由 OK
  • 404:检查 backend/main.py 是否包含:
    • from terminal_router import router as terminal_router
    • app.include_router(terminal_router)

Step 3确认前端 API_BASE 指向正确,并且已重启生效

cd ~/guanghu-dev/ghcs-mono/frontend
cat -n .env.local

推荐:

NEXT_PUBLIC_CONSOLE_API=http://127.0.0.1:5002

改完必须重启前端

npm run dev

Step 4确认“页面可用”与“后端可达”不是一回事

打开:http://localhost:3000/console/terminal

验收点:服务器下拉是否能显示(来自 Step 2 的 servers 列表)。


Step 5交互与焦点验收只看回显不看光标

连接成功后输入:

whoami
pwd
echo FOCUS_OK

期望回显:用户名、路径、FOCUS_OK

5.1 点击聚焦验收(对应历史 bug

  1. 点页面别处

  2. 点回黑框

  3. 输入:

echo CLICK_FOCUS_OK

期望回显 CLICK_FOCUS_OK

5.2 额外:判断是否一直保持输入通道

点页面别处后,不点回终端,直接键盘敲:

echo SHOULD_APPEAR
  • 若回显:说明输入通道仍在
  • 若不回显:说明焦点确实丢失,需要启用“保险带补丁”

3常见故障 → 快速定位表

  • 页面能开,但服务器下拉空:优先回到 Step 2/3路由未挂载或 API_BASE 未生效)
  • 连接按钮报 WS error:先跑 curl -i /ws/terminal/servers 判 200/404再看浏览器 Network → WS
  • 能连但不能输入:先用 echo 判输入通道是否断,再考虑焦点补丁
  • 输入重复:检查是否每次 connect 都重复绑定 xterm 的 onData(应只绑定一次或重连前清理)

3.5|关键数据备忘(防遗忘)

3.5.1 本地端口与环境变量

  • 后端console-apihttp://127.0.0.1:5002
  • 前端Next devhttp://localhost:3000
  • 前端环境变量文件:~/guanghu-dev/ghcs-mono/frontend/.env.local
    • NEXT_PUBLIC_CONSOLE_API=http://127.0.0.1:5002
    • ⊢ 改 .env.local 后必须重启 npm run dev 才会生效

3.5.2 登录与 Bearer tokenAPI Keys 写操作必用)

  • 登录接口:POST /api/login
  • 返回字段:access_token + token_type: bearer
  • 本地默认管理员账号(见 backend/auth.pyawen / guanghu2026
  • 前端 token 存储位置(本次约定):localStorage.ghcs_access_token
  • 写请求必须带 headerAuthorization: Bearer <access_token>

3.5.3 API Keys 关键接口(本次已验收)

  • GET /api/keys/suppliers(当前可不鉴权)
  • GET /api/keys/list(当前可不鉴权)
  • POST /api/keys/add(需鉴权)
  • PUT /api/keys/{id}(需鉴权;启停开关)
  • DELETE /api/keys/{id}(需鉴权)

4推荐的“保险带补丁”可选但建议保留

若遇到“点回黑框无法找回输入”,给终端容器外层加:

onMouseUp={() => term.current?.focus()}

这能把“点黑框回焦”变成确定性行为。


5本次会话验收回执可复制到执行记录

  • curl -i http://127.0.0.1:5002/ws/terminal/servers → 200
  • 终端回显:whoami / pwd / echo FOCUS_OK / echo CLICK_FOCUS_OK / echo SHOULD_APPEAR 全通过