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

架构设计

本文档介绍 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 加密

  1. 应用启动时生成自签名证书RSA 2048
  2. 证书存储在应用数据目录
  3. 所有 HTTP 传输使用 TLS 加密
  4. 客户端跳过证书验证(局域网内互信)

数据存储

  • SQLite 数据库存储在用户数据目录
  • 聊天记录、文件传输记录本地持久化
  • 设备信息定期清理过期数据