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