feat(server): 初始化 rtty-server 项目结构与基础依赖
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
/target
|
||||||
|
/.idea
|
||||||
|
/Cargo.lock
|
||||||
31
Cargo.toml
Normal file
31
Cargo.toml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
[package]
|
||||||
|
name = "rtty-server"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# 1. 异步运行时与 Web 框架
|
||||||
|
tokio = { version = "1.38", features = ["full"] }
|
||||||
|
axum = { version = "0.7", features = ["ws"] }
|
||||||
|
tower-http = { version = "0.5", features = ["cors", "trace"] }
|
||||||
|
|
||||||
|
# 2. PTY 驱动与终端状态引擎
|
||||||
|
portable-pty = "0.8"
|
||||||
|
alacritty_terminal = "0.24"
|
||||||
|
|
||||||
|
# 3. 序列化与数据传输 (支持移动端 JSON 重排协议)
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
# 4. 日志与并发工具
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
|
anyhow = "1.0"
|
||||||
|
dashmap = "6.0" # 高并发线程安全的 SessionMap
|
||||||
|
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = 3
|
||||||
|
lto = true
|
||||||
|
codegen-units = 1
|
||||||
|
strip = true
|
||||||
62
README.md
62
README.md
@@ -1,3 +1,61 @@
|
|||||||
# Rtty
|
# 🚀 Rtty 项目设计总结与架构指南
|
||||||
|
|
||||||
Rtty 是一款基于 Rust 与 Flutter 构建的高性能、跨平台虚拟终端系统,通过服务端状态保持与多端解耦渲染,实现 PC 端工业级 ANSI 兼容与移动端原生语义化重排。
|
## 📝 一句话描述
|
||||||
|
|
||||||
|
> **Rtty 是一款基于 Rust 与 Flutter 构建的高性能、跨平台虚拟终端系统,通过服务端状态保持与多端解耦渲染,实现 PC 端工业级 ANSI 兼容与移动端原生语义化重排。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ 系统整体架构图
|
||||||
|
|
||||||
|
```
|
||||||
|
┌───────────────────────────────┐
|
||||||
|
│ Rtty Server (Rust 后端) │
|
||||||
|
│ • portable-pty (进程/Shell) │
|
||||||
|
│ • alacritty_terminal (真相源)│
|
||||||
|
└───────────────┬───────────────┘
|
||||||
|
│
|
||||||
|
WebSocket (JSON / ANSI 字节流)
|
||||||
|
│
|
||||||
|
┌─────────────────────────┴─────────────────────────┐
|
||||||
|
▼ ▼
|
||||||
|
┌───────────────────────────────┐ ┌───────────────────────────────┐
|
||||||
|
│ Rtty Desktop (PC 客户端) │ │ Rtty Mobile (移动客户端) │
|
||||||
|
│ • flutter_alacritty (FFI) │ │ • Flutter Native Controls │
|
||||||
|
│ • Canvas 经典 ANSI 网格 │ │ • ListView + RichText 重排 │
|
||||||
|
│ • 100% 工业级 ANSI 兼容 │ │ • 自适应换行 / 卡片化 UI │
|
||||||
|
└───────────────────────────────┘ └───────────────────────────────┘
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ 核心组件与职责划分
|
||||||
|
|
||||||
|
### 1. **服务端内核 (`rtty-server`)**
|
||||||
|
|
||||||
|
* **`portable-pty`**:负责底层的 POSIX/Windows 伪终端创建、子进程(Shell/Bash/Zsh)拉起与文件描述符读写。
|
||||||
|
* **`alacritty_terminal`**:作为整个系统的“真相源 (Source of Truth)”,在内存中实时解析 ANSI 序列,维护 2D 屏幕网格(Grid)、光标位置及历史回滚缓冲区,同时提供断线重连时的快照恢复(Dump Screen Snapshot)。
|
||||||
|
* **`WebSocket (Axum/Tokio)`**:负责与各终端建立双向实时通信,分发事件流与控制信号。
|
||||||
|
|
||||||
|
### 2. **桌面端渲染管线 (`rtty-desktop`)**
|
||||||
|
|
||||||
|
* **`flutter_alacritty` (Rust FFI 绑定)**:PC 端放弃纯 Dart 的轻量级解析,直接调用本地 C-Bindings 共享 `alacritty_terminal` 的 Rust 渲染引擎。
|
||||||
|
* **渲染特性**:Canvas 纯网格高效绘制,保持对 `vim`、`htop`、`tmux` 等全屏 ANSI 软件的 100% 工业级兼容与真彩显示。
|
||||||
|
|
||||||
|
### 3. **移动端渲染管线 (`rtty-mobile`)**
|
||||||
|
|
||||||
|
* **Flutter Native 组件重排**:移动端抛弃传统 2D 字符网格,采用语义化数据拆解。
|
||||||
|
* **渲染特性**:
|
||||||
|
* **命令与输出**:封装为 `ListView` 卡片,支持文本按词软换行(Word Wrap),彻底消除横向滚动条与小字号看不清的痛点。
|
||||||
|
* **键盘与交互**:吸底 Command Input 配合移动端专属快捷键工具栏(Keybar)。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Rtty 的三大核心设计优势
|
||||||
|
|
||||||
|
1. **状态与渲染解耦**:服务端 Rust 负责维持单一终端状态,客户端按平台特性自由渲染。
|
||||||
|
2. **前后端内核统一**:后端与 PC 端共享 `alacritty_terminal` 引擎,解析行为 100% 绝对一致。
|
||||||
|
3. **移动端体验革新**:告别画面缩放与 TUI 错乱,用 Native UI 呈现命令行数据。
|
||||||
0
src/config.rs
Normal file
0
src/config.rs
Normal file
34
src/main.rs
Normal file
34
src/main.rs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
mod config;
|
||||||
|
mod terminal;
|
||||||
|
mod ws;
|
||||||
|
|
||||||
|
use axum::{routing::get, Router};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
||||||
|
pub struct AppState {
|
||||||
|
// 预留全局 Session 管理句柄
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> anyhow::Result<()> {
|
||||||
|
// 初始化日志
|
||||||
|
tracing_subscriber::registry()
|
||||||
|
.with(tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| "rtty_server=debug".into()))
|
||||||
|
.with(tracing_subscriber::fmt::layer())
|
||||||
|
.init();
|
||||||
|
|
||||||
|
let state = Arc::new(AppState {});
|
||||||
|
|
||||||
|
let app = Router::new()
|
||||||
|
.route("/ws", get(ws::handler::ws_route))
|
||||||
|
.with_state(state);
|
||||||
|
|
||||||
|
let addr = "0.0.0.0:8080";
|
||||||
|
tracing::info!("🚀 Rtty Server running on ws://{}", addr);
|
||||||
|
|
||||||
|
let listener = tokio::net::TcpListener::bind(addr).await?;
|
||||||
|
axum::serve(listener, app).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
0
src/terminal/engine.rs
Normal file
0
src/terminal/engine.rs
Normal file
2
src/terminal/mod.rs
Normal file
2
src/terminal/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
mod pty;
|
||||||
|
mod engine;
|
||||||
0
src/terminal/pty.rs
Normal file
0
src/terminal/pty.rs
Normal file
0
src/ws/handler.rs
Normal file
0
src/ws/handler.rs
Normal file
2
src/ws/mod.rs
Normal file
2
src/ws/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
pub(crate) mod handler;
|
||||||
|
mod protocol;
|
||||||
27
src/ws/protocol.rs
Normal file
27
src/ws/protocol.rs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// 客户端发送给 Rtty 服务端的控制指令
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(tag = "type", rename_all = "snake_case")]
|
||||||
|
pub enum ClientMessage {
|
||||||
|
/// 键盘/文本输入
|
||||||
|
Input { data: String },
|
||||||
|
/// 客户端请求 Resize
|
||||||
|
Resize { cols: u16, rows: u16 },
|
||||||
|
/// 客户端申明控制权 (用来解决多端控制冲突)
|
||||||
|
ClaimControl,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 服务端推送给客户端的消息 (分别适配 PC 和 移动端)
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(tag = "type", rename_all = "snake_case")]
|
||||||
|
pub enum ServerMessage {
|
||||||
|
/// 原生 ANSI 字节流 (供 PC 端 xterm/flutter_alacritty 渲染)
|
||||||
|
RawData { data: String },
|
||||||
|
/// 移动端专属:解耦后的语义化 JSON 屏显数据
|
||||||
|
MobileSnapshot {
|
||||||
|
cursor_x: usize,
|
||||||
|
cursor_y: usize,
|
||||||
|
lines: Vec<String>,
|
||||||
|
},
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user