41 lines
1.7 KiB
Markdown
41 lines
1.7 KiB
Markdown
|
|
# WebSSH 终端无法输入修复
|
||
|
|
|
||
|
|
**日期**: 2026-05-26
|
||
|
|
**变更摘要**: 修复 WebSSH 终端连接建立后立即断开、无法输入的问题
|
||
|
|
|
||
|
|
## 动机
|
||
|
|
|
||
|
|
1. WebSocket 连接建立后几秒内就断开(wsState=CLOSED),用户无法在终端输入
|
||
|
|
2. 后端日志报 `WebSSH shell creation failed: ` 错误消息为空,无法诊断
|
||
|
|
3. `finally` 块双重关闭 WebSocket 导致 `Unexpected ASGI message 'websocket.close'` 异常
|
||
|
|
4. 连接池复用的旧连接可能已失效(TCP连接在但SSH通道损坏),`create_process` 抛空消息异常
|
||
|
|
|
||
|
|
## 变更内容
|
||
|
|
|
||
|
|
### server/api/webssh.py — 3个bug修复
|
||
|
|
- **失效连接重试**: `create_process` 失败时,强制关闭池中旧连接,用新连接重试一次
|
||
|
|
- **异常信息改进**: `logger.error` 改用 `{type(e).__name__}: {e!r}` 避免空消息
|
||
|
|
- **双重关闭修复**: 引入 `ws_closed` 标志,异常分支 close 后 finally 不再重复 close
|
||
|
|
- 所有 `websocket.close()` 调用增加 try/except 防护
|
||
|
|
|
||
|
|
### web/app/terminal.html — Alpine 初始化竞态修复
|
||
|
|
- `$d()` 函数加 try/catch:Alpine 未加载时返回默认对象而非抛 `ReferenceError`
|
||
|
|
- 消除 `ResizeObserver fit error: ReferenceError: Alpine is not defined` 控制台警告
|
||
|
|
|
||
|
|
## 涉及文件
|
||
|
|
|
||
|
|
- `server/api/webssh.py` — WebSSH WebSocket 处理
|
||
|
|
- `web/app/terminal.html` — 前端终端页面
|
||
|
|
|
||
|
|
## 是否需迁移/重启
|
||
|
|
|
||
|
|
- 需重启后端(webssh.py 修改)
|
||
|
|
- terminal.html 静态文件无需重启
|
||
|
|
|
||
|
|
## 验证方式
|
||
|
|
|
||
|
|
1. 打开 terminal.html?server_id=8 → WebSocket 保持 OPEN
|
||
|
|
2. 输入 `whoami` → 回显 `root`
|
||
|
|
3. 后端日志无 `shell creation failed` 和 `Unexpected ASGI message` 错误
|
||
|
|
4. 控制台无 `Alpine is not defined` 警告
|