Files
terminal-lab/wetty/xterminal-wetty-diff.md
2026-03-03 16:07:18 +08:00

319 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# xterminal 与 wetty client 详细差异对比
## 1. 对比范围与结论
本文对比对象:
- `xterminal``/Users/gavin/lab/xterminal`
- `wetty` 当前项目前端 client`/Users/gavin/lab/wetty/src/client/wetty/**`(以及其页面与配置面板)
核心结论:
1. 两者不是同层替代关系。`xterminal` 是前端终端组件库,`wetty client` 是完整 Web SSH 网关客户端。
2. `wetty client` 的核心能力来自 `xterm.js` 真终端仿真;`xterminal` 核心是“CLI 交互组件”,终端协议能力主要由业务层补齐。
3. 若目标是“做 SSH/PTY 级别会话”,`wetty client` 路线更直接;若目标是“嵌入式 Web CLI 组件”,`xterminal` 更轻更可控。
---
## 2. 产品定位与边界
### xterminal组件库定位
- 对外是 `XTerminal` 类 API`mount/write/history/setCompleter/pause/resume/dispose`)。
- 不绑定任何固定后端协议,网络连接由业务方自行实现。
- 证据:
- `source/index.ts:14`(类定义)
- `source/index.ts:95`(挂载)
- `source/index.ts:53`(输出 API
- `source/index.ts:90`(补全)
### wetty client业务客户端定位
- 页面入口直接完成:终端初始化、断线重连 UI、网关连接、数据收发。
- 与运行配置、网关协议、页面 DOM 强耦合。
- 证据:
- `src/client/wetty.ts:26`(启动终端)
- `src/client/wetty.ts:38`socket 事件链)
- `src/client/wetty/socket.ts:43`(网关 socket 实现)
---
## 3. 渲染与终端仿真能力
### wetty clientxterm.js 终端仿真
- 直接继承 `@xterm/xterm``Terminal`
- 加载了 `FitAddon``WebLinksAddon``ImageAddon`
- 原生具备终端仿真语义(光标、控制序列、窗口 resize、链接识别等
- 证据:
- `src/client/wetty/term.ts:13`
- `src/client/wetty/term.ts:21`
- `src/client/wetty/term.ts:23`
- `src/client/wetty/term.ts:24`
### xterminal组件渲染模型
- 输出层以 HTML 片段写入为主。
- 核心库不自带完整 VT/ANSI 终端协议仿真。
- ANSI 处理与网关协议示例主要存在于 demo 脚本,不在库核心 API。
- 证据:
- `source/output/index.ts:40`
- `source/output/index.ts:49`
- `demo/main.js:381`ANSI 转换)
---
## 4. 输入模型差异(交互体验关键)
### wetty client按键流streaming input
- 用户每次按键通过 `term.onData` 立即发送到后端。
- 更接近真实 SSH TTY 行为(如逐字符编辑、交互式全屏程序)。
- 证据:
- `src/client/wetty.ts:60`
### xterminal行输入line-based
- 默认在 `Enter` 时触发 `data` 事件并提交一整行。
- 上下箭头与历史命令是组件内建行为。
- 证据:
- `source/instance.ts:136`Enter 分支)
- `source/instance.ts:141`emit data
- `source/instance.ts:147`(历史导航)
影响:
1. 需要 PTY 级“实时按键”时,`xterminal` 必须由业务层额外桥接按键事件。
2. 需要“类 REPL 文本命令输入”时,`xterminal` 默认体验更简单。
---
## 5. 协议与连接层
### wetty client内置网关协议适配
- 内建 `GatewaySocket`,封装事件 `connect/login/data/logout/disconnect/error`
- 支持 `init/stdin/resize/control` 帧。
- 自动处理 `ping/pong``connected``disconnect` 控制帧。
- 证据:
- `src/client/wetty/socket.ts:3`
- `src/client/wetty/socket.ts:57`
- `src/client/wetty/socket.ts:103`
- `src/client/wetty/socket.ts:238`
### xterminal协议在业务层demo实现
- 核心库无 WebSocket 协议绑定。
- demo 中手工实现网关连接、帧发送、回包处理、排队与批量 flush。
- 证据:
- `demo/main.js:635`connectByConfig
- `demo/main.js:572`handleGatewayFrame
- `demo/main.js:501`stdin 发送)
---
## 6. 配置系统与可配置能力
### wetty client
- 运行时读取 `/terminal.config.json`,并做最小字段校验、选中 server 逻辑。
- 有 iframe 配置面板,可改大量 xterm 选项并持久化 `localStorage.options`
- 证据:
- `src/client/wetty/runtimeConfig.ts:77`
- `src/client/wetty/runtimeConfig.ts:107`
- `src/client/wetty/term/confiruragtion.ts:8`
- `src/client/wetty/term/load.ts:10`
- `src/assets/xterm_config/index.html:62`
### xterminal
- 核心库配置简单(主要是挂载 target
- 无内建“终端参数 GUI 编辑器”,这部分由业务层自行实现。
- 证据:
- `source/types.d.ts:103`
---
## 7. 移动端策略对比
### wetty client
- 对 xterm 屏幕加 `contenteditable` 以触发软键盘。
- 页面内置功能键浮层方向键、Esc、Ctrl、Tab
- 证据:
- `src/client/wetty/mobile.ts:3`
- `index.html:28`
- `src/client/wetty/term.ts:190`
### xterminal
- 核心对移动端做了更系统处理:
- 隐藏 textarea + 自绘光标
- `visualViewport` 监听,动态补偿软键盘遮挡
- 避免 iOS Safari 聚焦导致 body 整体上推
- 证据:
- `source/instance.ts:58`
- `source/renderer/index.ts:27`
- `theme/index.css:68`
结论:
1. `wetty` 的移动端更偏“终端页面增强”。
2. `xterminal` 的移动端更偏“组件内部自洽”。
---
## 8. 安全与风险点
### 8.1 前端渲染安全
- `xterminal` 提供 `writeSafe/escapeHTML`,明确区分不可信文本输出路径。
- 证据:
- `source/index.ts:61`
- `source/output/index.ts:19`
- `wetty` 断线信息使用 `innerHTML` 注入文本,若消息来源不可信有注入风险。
- 证据:
- `src/client/wetty/disconnect.ts:9`
### 8.2 配置泄露风险
- 两边当前 `terminal.config.json` 都包含明文密码,属于高风险配置习惯(即使是开发环境)。
- 证据:
- `/Users/gavin/lab/wetty/terminal.config.json`
- `/Users/gavin/lab/xterminal/terminal.config.json`
---
## 9. 特性差异清单(功能维度)
### wetty client 独有/更强
1. xterm.js 终端仿真与 addon 生态。
2. 现成文件下载控制序列解析(`ESC[5i` / `ESC[4i`)。
3. 完整连接态 UIoverlay、reconnect、配置侧栏
4. 网关初始化载荷构造(含证书/私钥/密码多认证类型)。
证据:
- `src/client/wetty/download.ts:4`
- `src/client/wetty/download.ts:76`
- `src/client/wetty/socket.ts:161`
- `index.html:14`
### xterminal 独有/更强
1. 组件化 API 清晰,易嵌入任意前端。
2. 事件总线与资源释放边界明确(`dispose``register`)。
3. 历史记录与补全接口简洁。
4. 测试覆盖相对更系统input/output/history/emitter/xterminal
证据:
- `source/index.ts:117`
- `source/emitter/index.ts:16`
- `tests/xterminal.test.ts:4`
- `tests/input.test.ts:5`
---
## 10. 工程化与依赖体量
### 依赖与发布目标
- `wetty`
- 运行时依赖较重(含 `@xterm/*``express``socket.io``node-pty` 等)。
- 发布目标是应用(`bin/main` + server + client
- 证据:`package.json:44`dependencies
- `xterminal`
- 核心 runtime 无 dependencies仅 devDependencies
- 发布目标是库UMD + ESM + CSS + types
- 证据:`package.json:64`devDependencies`rollup.config.js:31`
### 产物规模(当前工作区构建结果)
- `wetty` client bundle`build/client/wetty.js``511K`(含 source map 更大)。
- `xterminal` dist`xterminal.esm.js``8.5K``xterminal.umd.js``16K`
结论:
1. 若只需要嵌入命令交互 UI`xterminal` 体量优势明显。
2. 若需要终端仿真,`wetty`/xterm.js 的体量属于能力成本。
---
## 11. 测试对比
- `wetty` 当前仓库测试集中在:
- 客户端 `FileDownloader`
- 服务端 shell escaping
- 证据:`src/client/wetty/download.spec.ts:10``src/server/shared/shell.spec.ts:5`
- `xterminal` 测试覆盖:
- `xterminal/input/output/history/emitter/disposable/reactivity`
- 证据:`/Users/gavin/lab/xterminal/tests/*.test.ts`
---
## 12. 当前项目内一个关键不一致点
在当前 `wetty` 仓库中,前端 client 已改为“网关 WebSocket 帧协议”,但后端原有代码仍是 Socket.IO 事件模型(`input/resize/commit`)。
- 前端证据:`src/client/wetty/socket.ts:97`
- 后端证据:`src/server/spawn.ts:38``src/server/socketServer/socket.ts:38`
这意味着:
1. 当前 client 与本仓库原 server 不天然对接。
2. client 实际更像在对接外部网关服务,而不是本地 wetty server。
---
## 13. 选型建议(按目标场景)
### 选 wetty client 路线
适合:
1. 目标是“浏览器里完整 SSH 终端”。
2. 需要 xterm.js 级别兼容能力(控制序列、终端行为一致性)。
3. 接受更重依赖与更复杂调试链路。
### 选 xterminal 路线
适合:
1. 目标是“可嵌入、可定制、轻量 CLI 组件”。
2. 协议、渲染、会话行为希望完全可控。
3. 可接受自行补齐 SSH/ANSI/PTY 的业务层逻辑。
---
## 14. 如果要做“xterminal + wetty 能力融合”,推荐最小改造路径
1. 保持 `xterminal` 作为 UI 输入输出壳,不直接替换为 xterm.js。
2. 单独抽出 `gateway client` 模块(`connect/send/receive/reconnect`),不要继续写在 demo/page 脚本。
3. 定义统一帧协议适配层,把 `init/stdin/resize/control/stdout/stderr/error` 规范化。
4. 将 ANSI 渲染器从 demo 抽为独立模块补测试尤其是跨帧、退格、CR/LF
5. 最后再评估是否有必要迁移到 xterm.js仅在终端兼容性成为瓶颈时
---
## 15. 风险清单(落地前需确认)
1. 明文密码配置必须替换(令牌化或后端临时凭据)。
2. 断线错误信息渲染方式应改为安全文本输出(避免 `innerHTML` 注入)。
3. 若要支持交互式全屏程序vim/top/tmux需确认输入模型是按键流而非行输入。
4. 若继续沿用移动端触控条,需要统一“焦点不丢失”的处理策略(当前两项目实现不同)。
---
## 16. 快速摘要(一页版)
1. `xterminal` 是“轻量终端 UI 组件库”;`wetty client` 是“完整 Web SSH 客户端”。
2. `wetty` 的强项是 xterm.js 终端仿真;`xterminal` 的强项是组件化、轻量、可嵌入。
3. 两者可融合,但不是无缝替换;最大差异在输入模型、协议耦合、终端仿真深度。
4. 当前 `wetty` 仓库里 client/server 协议模型存在分叉,后续演进需先统一架构方向。