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.
16 KiB
16 KiB
架构设计
本文档介绍 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)
全局单例,管理所有运行时状态:
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 加密
- 应用启动时生成自签名证书(RSA 2048)
- 证书存储在应用数据目录
- 所有 HTTP 传输使用 TLS 加密
- 客户端跳过证书验证(局域网内互信)
数据存储
- SQLite 数据库存储在用户数据目录
- 聊天记录、文件传输记录本地持久化
- 设备信息定期清理过期数据