系统架构
┌─────────────────┐ HTTP/WS ┌─────────────────┐ SSH ┌─────────────┐
│ 前端 (Vite) │ ◄──────────────► │ 后端 API │ ◄───────────► │ RRU 设备 │
│ 10.90.189.171 │ │ :8008 │ │ 网络设备 │
│ :5174 │ │ Python/Node? │ │ │
└─────────────────┘ └─────────────────┘ └─────────────┘
关键技术点
┌────────────┬───────────────────────────────────────────────┐
│ 功能 │ 实现方式 │
├────────────┼───────────────────────────────────────────────┤
│ SSH 连接 │ 后端使用 paramiko(Python)或 ssh2(Node.js) │
├────────────┼───────────────────────────────────────────────┤
│ 实时 Shell │ WebSocket + PTY(伪终端) │
├────────────┼───────────────────────────────────────────────┤
│ 终端模拟 │ 前端使用 xterm.js(猜测) │
├────────────┼───────────────────────────────────────────────┤
│ 多会话管理 │ session_id 区分不同设备连接 │
├────────────┼───────────────────────────────────────────────┤
│ 文件传输 │ SFTP / SCP │
└────────────┴───────────────────────────────────────────────┘
- 多设备同时连接
架构设计
┌──────────────────────────────────────────────────────────────┐
│ 后端服务 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Session Manager (会话管理器) │ │
│ │ │ │
│ │ sessions = { │ │
│ │ "session_001": { client: SSHClient, info: {...} }, │ │
│ │ "session_002": { client: SSHClient, info: {...} }, │ │
│ │ "session_003": { client: SSHClient, info: {...} }, │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
▲ ▲ ▲
│ SSH │ SSH │ SSH
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ RRU-A │ │ RRU-B │ │ RRU-C │
│ 10.x.x.1│ │ 10.x.x.2│ │ 10.x.x.3│
└─────────┘ └─────────┘ └─────────┘
- ushell 和普通 shell 的区别
概念对比
┌──────────┬──────────────────┬──────────────────────┐
│ 特性 │ 普通 Shell │ ushell │
├──────────┼──────────────────┼──────────────────────┤
│ 交互方式 │ 交互式,持续会话 │ 单次命令执行 │
├──────────┼──────────────────┼──────────────────────┤
│ 适用场景 │ 人工操作、调试 │ 自动化脚本、批量操作 │
├──────────┼──────────────────┼──────────────────────┤
│ 返回方式 │ 实时流式输出 │ 命令完成后返回结果 │
├──────────┼──────────────────┼──────────────────────┤
│ 进程环境 │ 登录 shell │ 指定进程上下文 │
└──────────┴──────────────────┴──────────────────────┘
一、多设备同时连接
架构设计
┌──────────────┐
│ 前端 │
└──────┬───────┘
│ HTTP/WS
▼
┌──────────────────────────────────────────────┐
│ 后端服务 │
│ ┌─────────────────────────────────────────┐ │
│ │ sessions: Map<session_id, SSHClient> │ │
│ │ │ │
│ │ session_1 ──► RRU设备A (10.x.x.x) │ │
│ │ session_2 ──► RRU设备B (10.y.y.y) │ │
│ │ session_3 ──► RRU设备C (10.z.z.z) │ │
│ └─────────────────────────────────────────┘ │
└──────────────────────────────────────────────┘
二、ushell 和普通 shell 的区别
概念对比
┌──────────┬─────────────────┬────────────────────────┐
│ 特性 │ 普通 Shell │ ushell │
├──────────┼─────────────────┼────────────────────────┤
│ 交互方式 │ 直接命令行 │ 进程内命令 │
├──────────┼─────────────────┼────────────────────────┤
│ 用途 │ 系统级命令 │ RRU 专用命令 │
├──────────┼─────────────────┼────────────────────────┤
│ 上下文 │ 独立 shell 进程 │ 特定进程内部 │
├──────────┼─────────────────┼────────────────────────┤
│ 典型场景 │ ls, cd, cat │ 查询小区状态、配置参数 │
└──────────┴─────────────────┴────────────────────────┘
RRU 中的 ushell
RRU 设备架构:
┌─────────────────────────────────────┐
│ RRU 设备 │
│ ┌─────────────────────────────┐ │
│ │ Linux Shell (bash/ush) │◄───┼─── 普通 Shell
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ 进程 A (L1) │ │
│ │ └─ ushell 接口 │◄───┼─── ushell -p L1
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ 进程 B (L2) │ │
│ │ └─ ushell 接口 │◄───┼─── ushell -p L2
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
三、SSH 断线重连
断线场景
-
网络波动 - 临时断开
-
设备重启 - 设备侧主动断开
-
超时断开 - 长时间无操作
-
服务重启 - 后端服务重启
四、文件上传下载
架构
上传流程:
┌────────┐ FormData ┌────────┐ SFTP ┌────────┐
│ 前端 │ ──────────────► │ 后端 │ ──────────► │ RRU │
│ 文件 │ │ API │ │ 设备 │
└────────┘ └────────┘ └────────┘
下载流程:
┌────────┐ 请求路径 ┌────────┐ SFTP ┌────────┐
│ 前端 │ ──────────────► │ 后端 │ ◄────────── │ RRU │
│ │ ◄────────────── │ API │ 文件流 │ 设备 │
│ Blob │ 文件流 └────────┘ └────────┘
└────────┘
总结
┌────────────┬─────────────────────┬────────────────────────────────────────────────────────┐
│ 功能模块 │ 关键技术 │ 核心 API │
├────────────┼─────────────────────┼────────────────────────────────────────────────────────┤
│ 多设备连接 │ 会话字典 + UUID │ POST /connect, GET /sessions │
├────────────┼─────────────────────┼────────────────────────────────────────────────────────┤
│ ushell │ 进程管道 + 输出解析 │ POST /command/ushell │
├────────────┼─────────────────────┼────────────────────────────────────────────────────────┤
│ 断线重连 │ 心跳检测 + 自动重连 │ GET /session/{id}/health, POST /session/{id}/reconnect │
├────────────┼─────────────────────┼────────────────────────────────────────────────────────┤
│ 文件传输 │ SFTP + 流式传输 │ POST /file/upload, POST /file/download │
└────────────┴─────────────────────┴────────────────────────────────────────────────────────┘
❯ web ushell是如何实现的?
● Web ushell 实现原理
整体架构
┌─────────────────────────────────────────────────────────────────────┐
│ 用户浏览器 │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ xterm.js (终端模拟器) │ │
│ │ - 渲染终端界面 │ │
│ │ - 捕获键盘输入 │ │
│ │ - 显示输出内容 │ │
│ └──────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
│ WebSocket (ws://host:8008/ws/shell/{session_id})
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 后端服务 │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ WebSocket Handler │ │
│ │ - 接收前端输入 │ │
│ │ - 转发到 SSH Channel │ │
│ │ - 回传输出到前端 │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ SSH Channel (PTY) │ │
│ │ paramiko.invoke_shell() → 伪终端 │ │
│ └──────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
│ SSH 协议
▼
┌─────────────────────────────────────────────────────────────────────┐
│ RRU 网络设备 │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Linux Shell │ │
│ │ bash / ush → 用户输入命令 │ │
│ │ ushell -p L1 → 进入进程内部命令行 │ │
│ └──────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘