You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

259 lines
16 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 架构设计
本文档介绍 Flash Send 的整体架构设计、模块划分和数据流。
## 整体架构
```
┌─────────────────────────────────────────────────────────────────┐
│ Flash Send │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Frontend (Vue 3) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ DeviceList│ │ChatWindow│ │FileTransfer│ │ Settings │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ Pinia Stores │ │ │
│ │ │ deviceStore | chatStore | settingsStore │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ Tauri API Layer │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ invoke / listen │
│ │ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Backend (Rust) │ │
│ │ ┌──────────────────────────────────────────────────┐ │ │
│ │ │ Tauri Commands │ │ │
│ │ │ discovery | chat | file | config │ │ │
│ │ └──────────────────────────────────────────────────┘ │ │
│ │ ┌──────────────────────────────────────────────────┐ │ │
│ │ │ AppState │ │ │
│ │ │ local_device | device_manager | connections │ │ │
│ │ └──────────────────────────────────────────────────┘ │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │ │
│ │ │ Discovery │ │ WebSocket │ │ HTTP │ │ │
│ │ │ (UDP) │ │ (WS) │ │ (HTTPS) │ │ │
│ │ └────────────┘ └────────────┘ └────────────────────┘ │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ Database (SQLite) │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
## 模块划分
### 前端模块 (src/)
```
src/
├── api/ # Tauri 命令封装
│ └── index.ts # 统一 API 导出
├── components/ # 可复用组件
│ ├── Sidebar.vue # 侧边导航栏
│ ├── DeviceCard.vue # 设备卡片
│ ├── MessageBubble.vue# 消息气泡
│ ├── ChatInput.vue # 聊天输入框
│ ├── FileProgress.vue # 文件传输进度
│ └── ...
├── pages/ # 页面组件
│ ├── DeviceList.vue # 设备列表页
│ ├── ChatWindow.vue # 聊天窗口页
│ ├── FileTransfer.vue # 文件传输页
│ └── Settings.vue # 设置页
├── stores/ # Pinia 状态管理
│ ├── deviceStore.ts # 设备状态
│ ├── chatStore.ts # 聊天状态
│ └── settingsStore.ts # 设置状态
├── hooks/ # 组合式函数
│ └── useEventListener.ts
├── types/ # TypeScript 类型定义
│ └── index.ts
└── router/ # Vue Router 路由
└── index.ts
```
### 后端模块 (src-tauri/src/)
```
src-tauri/src/
├── commands/ # Tauri 命令处理
│ ├── mod.rs # 命令注册
│ ├── discovery_commands.rs # 设备发现命令
│ ├── chat_commands.rs # 聊天命令
│ ├── file_commands.rs # 文件传输命令
│ └── config_commands.rs # 配置命令
├── discovery/ # UDP 设备发现
│ ├── mod.rs
│ ├── service.rs # 广播服务
│ └── manager.rs # 设备管理器
├── websocket/ # WebSocket 聊天
│ ├── mod.rs
│ ├── server.rs # WS 服务端
│ ├── client.rs # WS 客户端
│ ├── connection.rs # 连接管理
│ └── handler.rs # 消息处理
├── http/ # HTTP 文件传输
│ ├── mod.rs
│ ├── server.rs # HTTP 服务端
│ ├── client.rs # HTTP 客户端
│ └── handlers.rs # 请求处理器
├── tls/ # TLS 加密
│ ├── mod.rs
│ ├── certificate.rs # 证书生成
│ └── config.rs # TLS 配置
├── database/ # SQLite 数据库
│ ├── mod.rs
│ ├── schema.rs # 表结构定义
│ └── repository.rs # 数据操作
├── models/ # 数据模型
│ ├── mod.rs
│ ├── device.rs # 设备信息
│ ├── message.rs # 聊天消息
│ ├── file_transfer.rs # 文件传输
│ └── events.rs # 事件定义
├── utils/ # 工具函数
│ ├── mod.rs
│ ├── error.rs # 错误处理
│ └── config.rs # 应用配置
├── state.rs # 全局状态
├── main.rs # 程序入口
└── lib.rs # 库入口
```
## 数据流
### 1. 设备发现流程
```
┌──────────────┐ UDP Broadcast ┌──────────────┐
│ Device A │ ─────────────────────────────▶│ Device B │
│ │ Port 53317 │ │
│ │◀───────────────────────────── │ │
└──────────────┘ Response └──────────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ DeviceManager│ │ DeviceManager│
│ Add Device │ │ Add Device │
└──────────────┘ └──────────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Frontend │ │ Frontend │
│ device:found │ │ device:found │
└──────────────┘ └──────────────┘
```
### 2. 聊天消息流程
```
┌──────────────┐ ┌──────────────┐
│ Frontend A │ │ Frontend B │
│ send_message │ │ │
└──────────────┘ └──────────────┘
│ ▲
▼ │
┌──────────────┐ WebSocket ┌──────────────┐
│ WS Client A │ ─────────────────────────────▶│ WS Server B │
│ Port 53318 │ │ │
└──────────────┘ └──────────────┘
┌──────────────┐
│ Database │
│ save_message │
└──────────────┘
┌──────────────┐
│ Frontend │
│ chat:message │
└──────────────┘
```
### 3. 文件传输流程
```
┌──────────────┐ ┌──────────────┐
│ Sender │ │ Receiver │
│ select_file │ │ │
└──────────────┘ └──────────────┘
│ ▲
▼ │
┌──────────────┐ HTTPS POST ┌──────────────┐
│ HTTP Client │ ─────────────────────────────▶│ HTTP Server │
│ /upload │ Port 53319 │ │
│ multipart │◀ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │
└──────────────┘ Progress Events └──────────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Database │ │ Database │
│save_transfer │ │save_transfer │
└──────────────┘ └──────────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Frontend │ │ Frontend │
│file:progress │ │file:progress │
└──────────────┘ └──────────────┘
```
## 状态管理
### AppState (Rust)
全局单例,管理所有运行时状态:
```rust
pub struct AppStateInner {
pub local_device: RwLock<DeviceInfo>, // 本机设备信息
pub device_manager: DeviceManager, // 设备管理器
pub discovery_service: RwLock<Option<DiscoveryService>>,
pub ws_server: RwLock<Option<WsServer>>,
pub ws_client: RwLock<Option<WsClient>>,
pub http_server: RwLock<Option<HttpServer>>,
pub http_client: HttpClient,
pub connection_manager: ConnectionManager, // WebSocket 连接
pub app_data_dir: PathBuf, // 数据目录
pub transfer_cancellation_tokens: RwLock<HashMap<String, CancellationToken>>,
}
```
### Pinia Stores (Vue)
- **deviceStore**: 管理在线设备列表
- **chatStore**: 管理聊天消息、文件传输状态
- **settingsStore**: 管理应用设置(主题、设备名等)
## 事件系统
后端通过 Tauri 事件向前端推送实时更新:
| 事件名 | 说明 | 数据 |
|--------|------|------|
| `device:found` | 发现新设备 | DeviceInfo |
| `device:lost` | 设备离线 | device_id |
| `chat:message` | 收到聊天消息 | ChatMessage |
| `file:progress` | 文件传输进度 | TransferProgressEvent |
## 安全设计
### TLS 加密
1. 应用启动时生成自签名证书RSA 2048
2. 证书存储在应用数据目录
3. 所有 HTTP 传输使用 TLS 加密
4. 客户端跳过证书验证(局域网内互信)
### 数据存储
- SQLite 数据库存储在用户数据目录
- 聊天记录、文件传输记录本地持久化
- 设备信息定期清理过期数据