chore(doc):Update document

Update the document to include the latest changes: file continuation, introduction of Zustand to the front-end architecture.
This commit is contained in:
david_bai
2025-08-24 08:46:17 +08:00
parent a1a70bbff5
commit a0486da313
8 changed files with 1719 additions and 57 deletions
+31 -25
View File
@@ -6,13 +6,13 @@ This document provides a high-level overview of the PrivyDrop project's overall
The PrivyDrop system is primarily composed of the following core parts:
1. **Frontend**: A Single Page Application (SPA) built with Next.js. It's the interface users interact with, responsible for handling file selection, UI presentation, and initiating WebRTC connections.
1. **Frontend**: A Single Page Application (SPA) built with Next.js. It's the interface users interact with, responsible for handling file selection and UI presentation. It features a modern, layered architecture with a clear separation between the UI (React Components), centralized state management (Zustand), and the core WebRTC business logic, which is encapsulated in a framework-agnostic service layer.
2. **Backend**: A server built with Node.js and Express. It does not handle any file data. Its core responsibilities are:
- **Signaling Service**: Implemented with Socket.IO, it relays signaling messages (like SDP and ICE Candidates) for the "handshake" process before a WebRTC connection is established.
- **Room Management**: Handles the creation, joining, and status checking of rooms.
- **API Service**: Provides auxiliary HTTP endpoints.
3. **Redis**: An in-memory database used by the backend to store temporary data, such as room information and lists of participants, utilizing its TTL feature for automatic cleanup of expired rooms.
4. **TURN/STUN Server (Optional)**: Used to assist WebRTC with NAT traversal, ensuring a higher success rate for P2P connections in complex network environments. STUN is used to discover public IP addresses, while TURN serves as a fallback relay server. (This feature is not enabled by default in the current setup).
4. **TURN/STUN Server (Optional)**: Used to assist WebRTC with NAT traversal, ensuring a higher success rate for P2P connections in complex network environments. STUN is used to discover public IP addresses, while TURN serves as a fallback relay server.
## 2. Data Flow and Interaction Diagram
@@ -20,11 +20,17 @@ The following diagram illustrates the main flow for users establishing a connect
```mermaid
graph TD
subgraph "User A's Browser"
ClientA[Frontend UI]
subgraph "User A's Browser (Frontend)"
ClientA[UI Components] --> HooksA[Hooks Layer]
HooksA --> StoreA[Zustand Store]
HooksA --> ServiceA[WebRTC Service]
ServiceA --> StoreA
end
subgraph "User B's Browser"
ClientB[Frontend UI]
subgraph "User B's Browser (Frontend)"
ClientB[UI Components] --> HooksB[Hooks Layer]
HooksB --> StoreB[Zustand Store]
HooksB --> ServiceB[WebRTC Service]
ServiceB --> StoreB
end
subgraph "Server Infrastructure"
@@ -34,40 +40,40 @@ graph TD
TURN[TURN/STUN Server]
end
ClientA -- 1. Create/Join Room (HTTP/Socket) --> Nginx
ServiceA -- 1. Create/Join Room (HTTP/Socket) --> Nginx
Nginx --> Backend
Backend -- Read/Write Room Status --> Redis
ClientB -- 2. Join Same Room (HTTP/Socket) --> Nginx
ServiceB -- 2. Join Same Room (HTTP/Socket) --> Nginx
Backend -- 3. Broadcast user join event --> ClientA
Backend -- 3. Broadcast user join event --> ClientB
Backend -- 3. Broadcast user join event --> ServiceA
Backend -- 3. Broadcast user join event --> ServiceB
ClientA -- 4. Send Signal (Offer/ICE) --> Backend
Backend -- 5. Forward Signal --> ClientB
ClientB -- 6. Send Signal (Answer/ICE) --> Backend
Backend -- 7. Forward Signal --> ClientA
ServiceA -- 4. Send Signal (Offer/ICE) --> Backend
Backend -- 5. Forward Signal --> ServiceB
ServiceB -- 6. Send Signal (Answer/ICE) --> Backend
Backend -- 7. Forward Signal --> ServiceA
ClientA <-.-> |8.&nbsp;STUN Check| TURN
ClientB <-.-> |8.&nbsp;STUN Check| TURN
ServiceA <-.-> |8.&nbsp;STUN Check| TURN
ServiceB <-.-> |8.&nbsp;STUN Check| TURN
ClientA <-..- |9.&nbsp;P2P Direct Data Transfer| ClientB
ClientA <-.-> |9.&nbsp;TURN Relayed Data Transfer| TURN
ClientB <-.-> |9.&nbsp;TURN Relayed Data Transfer| TURN
ServiceA <-..- |9.&nbsp;P2P Direct Data Transfer| ServiceB
ServiceA <-.-> |9.&nbsp;TURN Relayed Data Transfer| TURN
ServiceB <-.-> |9.&nbsp;TURN Relayed Data Transfer| TURN
```
**Flow Description:**
1. **Room Creation/Joining**: User A (the sender) requests the backend to create a unique room ID via the frontend. The backend records this room in Redis.
2. **Sharing & Joining**: User A shares the room ID with User B via a link or QR code. User B uses this ID to request joining the room.
1. **Room Creation/Joining**: User A's frontend service layer requests the backend to create a unique room ID. The backend records this room in Redis.
2. **Sharing & Joining**: User A shares the room ID with User B. User B's frontend service layer uses this ID to request joining the room.
3. **Signaling Exchange**:
- Once there are two or more users in a room, they begin exchanging WebRTC signaling messages through the backend's Socket.IO service.
- This process includes exchanging network information (ICE candidates) and session descriptions (SDP offers/answers). The backend server acts merely as a "postman" for these messages, forwarding them without understanding their content.
- Once there are two or more users in a room, their respective `WebRTC Service` instances begin exchanging signaling messages through the backend's Socket.IO service.
- This process includes exchanging network information (ICE candidates) and session descriptions (SDP offers/answers). The backend server acts merely as a "postman" for these messages.
4. **NAT Traversal**: The browsers use the network information obtained from the signals, along with STUN/TURN servers, to attempt and establish a direct P2P connection.
5. **P2P Connection Established**: Once the connection is successfully established, all file and text data are transferred directly between User A's and User B's browsers, without passing through any server. If a direct connection fails, data will be relayed through a TURN server.
5. **P2P Connection Established**: Once the connection is successfully established—which in most cases is a direct peer-to-peer link—all file and text data are transferred directly between User A's and User B's browsers via their `WebRTC Service` instances, without passing through any server. In the rare case of highly restrictive networks where a direct connection cannot be established, data will be relayed through a TURN server. Even in this relayed mode, the data remains end-to-end encrypted by WebRTC and is not visible to the TURN server.
## 3. Design Philosophy
- **Privacy First**: Core file data is never uploaded to the server. The server only acts as an "introducer" or "matchmaker."
- **Frontend-Backend Separation**: Responsibilities are clearly separated. The frontend handles all user interaction and the complex logic of WebRTC; the backend provides lightweight, efficient signaling and room management services.
- **Horizontal Scalability**: The backend is stateless (with state managed in Redis), which theoretically allows it to be scaled horizontally by adding more Node.js instances to handle a large volume of concurrent signaling requests.
- **Horizontal Scalability**: The backend is stateless (with state managed in Redis), which theoretically allows it to be scaled horizontally by adding more Node.js instances to handle a large volume of concurrent signaling requests.
+30 -24
View File
@@ -6,13 +6,13 @@
PrivyDrop 系统主要由以下几个核心部分组成:
1. **前端 (Frontend)**: 一个使用 Next.js 构建的单页应用 (SPA)。它是用户直接交互的界面,负责处理文件选择UI 展示、发起 WebRTC 连接等所有客户端逻辑。
1. **前端 (Frontend)**: 一个使用 Next.js 构建的单页应用 (SPA)。它是用户直接交互的界面,负责处理文件选择UI 展示。其内部采用现代化的分层架构,清晰地分离了 UI (React 组件)、中心化状态管理 (Zustand) 以及封装在框架无关的服务层中的核心 WebRTC 业务逻辑。
2. **后端 (Backend)**: 一个使用 Node.js 和 Express 构建的服务器。它不处理任何文件数据,其核心职责是:
- **信令服务 (Signaling)**: 通过 Socket.IO 实现,为 WebRTC 连接建立前的“握手”过程传递信令消息 (如 SDP 和 ICE Candidates)。
- **房间管理 (Room Management)**: 处理房间的创建、加入和状态检查。
- **API 服务**: 提供一些辅助性的 HTTP 接口。
3. **Redis**: 一个内存数据库,用于后端存储临时数据,如房间信息、房间内的用户列表等,并利用其 TTL 特性自动清理过期房间。
4. **TURN/STUN 服务器【可选】**: 用于辅助 WebRTC 进行 NAT 穿透,确保在复杂网络环境下的 P2P 连接成功率。STUN 用于发现公网地址,TURN 则作为最后的备选方案,当中继服务器使用(目前没有使用这个特性)
4. **TURN/STUN 服务器【可选】**: 用于辅助 WebRTC 进行 NAT 穿透,确保在复杂网络环境下的 P2P 连接成功率。STUN 用于发现公网地址,TURN 则作为最后的备选方案,当中继服务器使用。
## 二、数据流与交互图
@@ -20,11 +20,17 @@ PrivyDrop 系统主要由以下几个核心部分组成:
```mermaid
graph TD
subgraph "用户A 浏览器"
ClientA[Frontend UI]
subgraph "用户A 浏览器 (前端)"
ClientA[UI 组件] --> HooksA[Hooks 层]
HooksA --> StoreA[Zustand Store]
HooksA --> ServiceA[WebRTC 服务]
ServiceA --> StoreA
end
subgraph "用户B 浏览器"
ClientB[Frontend UI]
subgraph "用户B 浏览器 (前端)"
ClientB[UI 组件] --> HooksB[Hooks 层]
HooksB --> StoreB[Zustand Store]
HooksB --> ServiceB[WebRTC 服务]
ServiceB --> StoreB
end
subgraph "服务器基础设施"
@@ -34,37 +40,37 @@ graph TD
TURN[TURN/STUN 服务器]
end
ClientA -- 1.&nbsp;创建/加入房间 (HTTP/Socket) --> Nginx
ServiceA -- 1.&nbsp;创建/加入房间 (HTTP/Socket) --> Nginx
Nginx --> Backend
Backend -- 读/写房间状态 --> Redis
ClientB -- 2.&nbsp;加入同一房间 (HTTP/Socket) --> Nginx
ServiceB -- 2.&nbsp;加入同一房间 (HTTP/Socket) --> Nginx
Backend -- 3.&nbsp;广播用户加入事件 --> ClientA
Backend -- 3.&nbsp;广播用户加入事件 --> ClientB
Backend -- 3.&nbsp;广播用户加入事件 --> ServiceA
Backend -- 3.&nbsp;广播用户加入事件 --> ServiceB
ClientA -- 4.&nbsp;发送信令 (Offer/ICE) --> Backend
Backend -- 5.&nbsp;转发信令 --> ClientB
ClientB -- 6.&nbsp;发送信令 (Answer/ICE) --> Backend
Backend -- 7.&nbsp;转发信令 --> ClientA
ServiceA -- 4.&nbsp;发送信令 (Offer/ICE) --> Backend
Backend -- 5.&nbsp;转发信令 --> ServiceB
ServiceB -- 6.&nbsp;发送信令 (Answer/ICE) --> Backend
Backend -- 7.&nbsp;转发信令 --> ServiceA
ClientA <-.-> |8.&nbsp;STUN检查| TURN
ClientB <-.-> |8.&nbsp;STUN检查| TURN
ServiceA <-.-> |8.&nbsp;STUN检查| TURN
ServiceB <-.-> |8.&nbsp;STUN检查| TURN
ClientA <-..- |9.&nbsp;P2P直连数据传输| ClientB
ClientA <-.-> |9.&nbsp;TURN中继数据传输| TURN
ClientB <-.-> |9.&nbsp;TURN中pey数据传输| TURN
ServiceA <-..- |9.&nbsp;P2P直连数据传输| ServiceB
ServiceA <-.-> |9.&nbsp;TURN中继数据传输| TURN
ServiceB <-.-> |9.&nbsp;TURN中数据传输| TURN
```
**流程说明:**
1. **房间创建/加入**: 用户 A(发送方)通过前端请求后端创建一个唯一的房间 ID。后端在 Redis 中记录该房间。
2. **分享与加入**: 用户 A 通过链接或二维码将房间 ID 分享给用户 B。用户 B 使用此 ID 请求加入房间。
1. **房间创建/加入**: 用户 A 的前端服务层请求后端创建一个唯一的房间 ID。后端在 Redis 中记录该房间。
2. **分享与加入**: 用户 A 将房间 ID 分享给用户 B。用户 B 的前端服务层使用此 ID 请求加入房间。
3. **信令交换**:
- 一旦房间内有两位或更多用户,他们便开始通过后端的 Socket.IO 服务交换 WebRTC 信令。
- 这个过程包括交换网络信息 (ICE candidates) 和会话描述 (SDP offers/answers)。后端服务器仅作为这些信令消息的“邮差”,进行转发,不理解其内容
- 一旦房间内有两位或更多用户,他们各自的 `WebRTC Service` 实例便开始通过后端的 Socket.IO 服务交换信令。
- 这个过程包括交换网络信息 (ICE candidates) 和会话描述 (SDP offers/answers)。后端服务器仅作为这些信令消息的“邮差”。
4. **NAT 穿透**: 浏览器利用从信令中获取的网络信息,并借助 STUN/TURN 服务器来尝试建立直接的 P2P 连接。
5. **P2P 连接建立**: 一旦连接建立成功,所有文件和文本数据都将直接在用户 A 和用户 B 的浏览器之间传输,不再经过任何服务器。如果直连失败,数据将通过 TURN 服务器进行中继
5. **P2P 连接建立**: 一旦连接成功建立——在绝大多数情况下是直接的点对点链路——所有文件和文本数据都将直接在用户 A 和用户 B 的浏览器之间通过各自的 `WebRTC Service` 实例进行传输,不再经过任何服务器。在少数网络环境极其复杂、无法建立直连的情况下,数据将通过 TURN 服务器进行中继。即便是在中继模式下,数据依然由 WebRTC 进行端到端加密,TURN 服务器无法窥探其内容
## 三、设计哲学