Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc [SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
5.8 KiB
5.8 KiB
GHCS v0.2 终端排障 SOP(SSH Web Terminal Debug SOP)
1|本次问题的具体原因(复盘结论)
1.1 真正卡住不是一个 bug,而是三层叠加
- 页面 200 ≠ 终端可用
/console/terminal返回 200 只说明 Next 页面渲染成功。- 终端真正依赖:
GET /ws/terminal/servers+WS /ws/terminal/{server_key}。 - 只要后端路由未挂载、或前端没打到正确后端,页面仍 200,但终端必失败。
- 环境变量未生效 / localhost 解析导致“像玄学”
NEXT_PUBLIC_CONSOLE_API改了但未重启前端 → Next 继续用旧值。localhost在部分环境可能走 IPv6(::1)而后端仅在 IPv4(127.0.0.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 ...回显
2|GHCS v0.2 终端排障 SOP(五段式,不跳步)
Step 0|准备(两窗口)
- 终端 A:backend(FastAPI)
- 终端 B:frontend(Next.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_routerapp.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)
-
点页面别处
-
点回黑框
-
输入:
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-api):
http://127.0.0.1:5002 - 前端(Next dev):
http://localhost:3000 - 前端环境变量文件:
~/guanghu-dev/ghcs-mono/frontend/.env.localNEXT_PUBLIC_CONSOLE_API=http://127.0.0.1:5002- ⊢ 改
.env.local后必须重启npm run dev才会生效
3.5.2 登录与 Bearer token(API Keys 写操作必用)
- 登录接口:
POST /api/login - 返回字段:
access_token+token_type: bearer - 本地默认管理员账号(见
backend/auth.py):awen / guanghu2026 - 前端 token 存储位置(本次约定):
localStorage.ghcs_access_token - 写请求必须带 header:
Authorization: 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全通过