206 lines
5.8 KiB
Markdown
Raw Normal View History

# GHCS v0.2 终端排障 SOPSSH Web Terminal Debug SOP
<aside>
🎯
本页用途:当 GHCS v0.2 的 SSH Web 终端出现「页面能开但连不上 / 能连但不能输入 / 焦点丢失 / 反复修不好」时,按固定流程快速定位。
原则:**先排通路,再看交互**先用可观测证据HTTP 状态码 / 命令回显),不要凭“光标看起来在不在”。
</aside>
---
## 1本次问题的具体原因复盘结论
### 1.1 真正卡住不是一个 bug而是三层叠加
1) **页面 200 ≠ 终端可用**
- `/console/terminal` 返回 200 只说明 Next 页面渲染成功。
- 终端真正依赖:`GET /ws/terminal/servers` + `WS /ws/terminal/{server_key}`
- 只要后端路由未挂载、或前端没打到正确后端,页面仍 200但终端必失败。
2) **环境变量未生效 / [localhost](http://localhost) 解析导致“像玄学”**
- `NEXT_PUBLIC_CONSOLE_API` 改了但未重启前端 → Next 继续用旧值。
- `localhost` 在部分环境可能走 IPv6`::1`)而后端仅在 IPv4`127.0.0.1`)监听 → 表现为偶发连不上 / 重试。
3) **焦点判断误区:光标渲染 ≠ 键盘输入通道**
- 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确认后端在跑
```bash
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 已挂载(最关键一锤)
```bash
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 指向正确,并且已重启生效
```bash
cd ~/guanghu-dev/ghcs-mono/frontend
cat -n .env.local
```
推荐:
```
NEXT_PUBLIC_CONSOLE_API=http://127.0.0.1:5002
```
**改完必须重启前端**
```bash
npm run dev
```
---
### Step 4确认“页面可用”与“后端可达”不是一回事
打开:`http://localhost:3000/console/terminal`
验收点:服务器下拉是否能显示(来自 Step 2 的 servers 列表)。
---
### Step 5交互与焦点验收只看回显不看光标
连接成功后输入:
```bash
whoami
pwd
echo FOCUS_OK
```
期望回显:用户名、路径、`FOCUS_OK`
#### 5.1 点击聚焦验收(对应历史 bug
1) 点页面别处
2) 点回黑框
3) 输入:
```bash
echo CLICK_FOCUS_OK
```
期望回显 `CLICK_FOCUS_OK`
#### 5.2 额外:判断是否一直保持输入通道
点页面别处后,**不点回终端**,直接键盘敲:
```bash
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.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.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推荐的“保险带补丁”可选但建议保留
若遇到“点回黑框无法找回输入”,给终端容器外层加:
```tsx
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` 全通过