# WebSSH 终端输入回显延迟修复 **日期**: 2026-05-26 **变更摘要**: 修复 WebSSH 终端输入字符不即时显示的问题 — 将 async-for (readline) 改为 read() + 降低 bufsize ## 动机 1. 用户在终端输入字符后,字符不会即时显示(echo 延迟),必须按 Enter 后才一次性出现 2. 根因:`async for data in shell.stdout` 内部调用 `readline()` → `readuntil('\n')`,会缓冲所有数据直到遇到换行符 3. 交互式终端中,单字符 echo 永远不包含换行符,导致所有输入字符被缓冲直到用户按 Enter ## 变更内容 ### server/api/webssh.py — 2处修改 **修改1: `_read_shell_output()` 函数 — 消除 readline 缓冲** - 旧:`async for data in shell.stdout:` (内部 readline,等换行才 yield) - 新:`while not shell.stdout.at_eof(): data = await shell.stdout.read(4096)` (有数据即返回) - `read(n)` 使用 `exact=False`,只要缓冲区有数据就立即返回(最多 n 字节),不等换行 **修改2: `create_process()` 调用 — 降低 bufsize** - 旧:`conn.create_process(term_type="xterm-256color", term_size=(24, 80))` (默认 bufsize=128KB) - 新:`conn.create_process(term_type="xterm-256color", term_size=(24, 80), bufsize=4096)` - 两处 create_process(主连接 + 失效重试连接)均添加 `bufsize=4096` - 4KB 缓冲区足够单次交互 echo,同时大幅降低延迟 ## 技术分析 asyncssh 数据流路径: ``` async for data in shell.stdout → SSHStreamProcess.__aiter__() → SSHStreamSession.aiter() → readline() → readuntil('\n') ← 阻塞直到换行符 ``` 修复后路径: ``` while not shell.stdout.at_eof(): data = await shell.stdout.read(4096) → SSHStreamSession.read(4096, exact=False) ← 有数据即返回 ``` ## 涉及文件 - `server/api/webssh.py` — WebSSH WebSocket 处理(2处修改) ## 是否需迁移/重启 - 需重启后端(webssh.py 修改) - 前端无改动 ## 验证方式 1. 打开 terminal.html?server_id=8 → WebSocket 保持 OPEN,状态显示「已连接」 2. 输入 `whoami` → 字符即时显示(不等 Enter),按 Enter 后立即显示 `root` 3. 后端日志无 `shell creation failed` 错误 4. 终端交互流畅,无 echo 延迟