Architecture Documentation
April 12, 2026 ยท View on GitHub
This document details the technical architecture, design decisions, and implementation details of 0trace.
๐ Overall Architecture
System Architecture Diagram
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
โ Sender โ โ Receiver โ
โ Browser โ โ Browser โ
โ โ โ โ
โ WebRTC โ โ WebRTC โ
โ JavaScript โ โ JavaScript โ
โโโโโโโโฌโโโโโโโ โโโโโโโโฌโโโโโโโ
โ โ
โ WebSocket Signaling โ WebSocket Signaling
โ (SDP/ICE) โ (SDP/ICE)
โ โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโผโโโโโโ
โ Rust โ
โ Backend โ
โ โ
โ Axum โ
โ + Tokio โ
โ + WebSocketโ
โโโโโโโโโโโโโ
โ
โ Signaling relay
โ Room management
โ
โโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโ
โ โ
โโโโโโโโผโโโโโโโ โโโโโโโโผโโโโโโโ
โ Sender โ โ Receiver โ
โ DataChannelโโโโโโP2P Directโโโโโโบโ DataChannelโ
โ (File Data)โ (DTLS encrypted) โ (File Data)โ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
Core Workflow
- Room Creation: Sender creates a room, gets an 8-digit pickup code
- Signaling Exchange: Both parties exchange SDP and ICE candidates via WebSocket
- P2P Connection: WebRTC establishes peer-to-peer connection with multiple STUN servers
- File Transfer: Transfer file data via DataChannel (streaming mode for large files)
- Auto Cleanup: Room automatically expires after 5 minutes of inactivity
- Keep-Alive: WebSocket heartbeat and auto-reconnect maintain connection stability
๐๏ธ Technology Stack
Backend
| Component | Version | Purpose |
|---|---|---|
| Rust | 1.75+ | Systems programming language |
| Axum | 0.7 | Web framework |
| Tokio | 1.35 | Async runtime |
| Tower | 0.4 | Middleware |
| Serde | 1.0 | Serialization/deserialization |
Frontend
| Component | Description |
|---|---|
| Vanilla JavaScript | No framework, stays lightweight |
| WebRTC API | Browser-native P2P |
| WebSocket API | Signaling communication |
| Fetch API | HTTP requests |
Protocols
- Signaling Protocol: WebSocket + JSON
- Transport Protocol: WebRTC DataChannel
- Encryption: DTLS/SRTP (WebRTC built-in)
๐ Project Structure
0trace/
โโโ shared/ # Shared library
โ โโโ src/
โ โ โโโ lib.rs # Library entry point
โ โ โโโ protocol.rs # Protocol definitions
โ โ โ โโโ SignalMessage # Signaling messages
โ โ โ โโโ TransferMessage # Transfer messages
โ โ โโโ room.rs # Room logic
โ โ โโโ RoomStatus # Room status
โ โ โโโ generate_code() # Pickup code generation
โ โโโ Cargo.toml
โ
โโโ backend/ # Backend service
โ โโโ src/
โ โ โโโ main.rs # Server entry point
โ โ โ โโโ HTTP routes
โ โ โ โโโ Static file service
โ โ โ โโโ CORS configuration
โ โ โโโ room.rs # Room manager
โ โ โ โโโ RoomManager # Room management
โ โ โ โโโ create_room() # Create room
โ โ โ โโโ join_room() # Join room
โ โ โ โโโ cleanup_expired()# Cleanup expired rooms
โ โ โโโ ws.rs # WebSocket handling
โ โ โโโ handle_ws() # Connection handling
โ โ โโโ forward_signal() # Signaling relay
โ โโโ static/ # Static files (production)
โ โโโ Cargo.toml
โ
โโโ frontend/ # Frontend development
โโโ static/
โโโ index.html # Main page
โโโ app.js # Core logic
โ โโโ WebRTCConnection # WebRTC management
โ โโโ App # UI control
โโโ style.css # Styles
โโโ i18n.js # Multilingual system
โโโ i18n/ # Translation files
โโโ zh-CN.json
โโโ en.json
โโโ ja.json
โโโ ko.json
โโโ es.json
โโโ fr.json
๐ API Design
HTTP API
Create Room
POST /api/create-room
Response: {"success": true, "code": "ABC123"}
Query Room
GET /api/room-info?code=ABC123
Response: {"exists": true, "sender_connected": true, "receiver_connected": false}
WebSocket API
Connection
ws://localhost:2029/api/ws?code=ABC123&role=sender
Signaling Messages
// Offer
{"type": "offer", "sdp": "..."}
// Answer
{"type": "answer", "sdp": "..."}
// ICE Candidate
{"type": "ice-candidate", "candidate": "..."}
// Peer joined
{"type": "peer-joined", "role": "receiver"}
// Peer left
{"type": "peer-left"}
// Error
{"type": "error", "message": "..."}
๐ Security Design
Transport Security
-
WebRTC Encryption
- DTLS (Datagram Transport Layer Security)
- SRTP (Secure Real-time Transport Protocol)
- End-to-end encryption, server cannot decrypt
-
Signaling Security
- WebSocket connection (WSS in production)
- Pickup code verification
- Room capacity limit (max 2 people)
-
Data Privacy
- Zero server storage
- Only forwards signaling messages
- No file content logging
Room Security
Pickup Code Design
const CHARS: &[u8] = b"123456789ABCDEFGHIJKLMNPQRSTUVWXYZ";
// Excludes 0 and O to avoid confusion
// $34^{6}$ โ 1.5 billion combinations
Expiration Mechanism
- Creation timestamp recorded
- Auto-cleanup after 1 hour
- Periodic scan for expired rooms
๐ก Transfer Protocol
File Transfer Flow
1. Sender โ Receiver: File metadata
{"type": "file-meta", "name": "test.jpg", "size": 1024000, "mimeType": "image/jpeg"}
2. Sender โ Receiver: Chunk info + data
{"type": "chunk-info", "index": 0, "total": 4}
[ArrayBuffer: 256KB data]
3. Repeat step 2 until all chunks transferred
4. Sender โ Receiver: Transfer complete
{"type": "complete"}
5. Receiver: Assemble file and trigger download
Chunking Strategy
const CHUNK_SIZE = 256 * 1024; // 256KB
// Advantages:
// - Reduces memory footprint
// - Real-time progress updates
// - Supports large files
// - Lowers transfer failure risk
๐จ Frontend Design
WebRTC Connection Management
class WebRTCConnection {
constructor() {
this.pc = null; // RTCPeerConnection
this.dc = null; // RTCDataChannel
this.ws = null; // WebSocket
this.role = null; // 'sender' | 'receiver'
}
// Core methods
async createRoom() // Create room
async joinRoom(code) // Join room
setupPeerConnection() // Setup PeerConnection
setupDataChannel() // Setup DataChannel
async sendFile(file) // Send file
handleFileReceive() // Receive file
}
UI Control
class App {
constructor() {
this.connection = null;
this.selectedFiles = null;
}
// Core methods
async init() // Initialize (i18n + events)
initModals() // Initialize modals
handleFilesSelect(files) // Handle file selection
async sendFiles() // Send multiple files
async joinRoom(code) // Join room
showToast(message, type) // Show notification
}
Multilingual System
class I18n {
async init() // Initialize (auto-detect language)
async loadLanguage(lang) // Load translation file
t(key) // Translation function
updateUI() // Update UI text
}
// Usage
i18n.t('send.copyLink') // โ "Copy Link"
๐ State Management
Room State
pub struct Room {
pub code: String,
pub created_at: Instant,
pub sender: Option<SplitSink<WebSocket, Message>>,
pub receiver: Option<SplitSink<WebSocket, Message>>,
}
pub enum RoomStatus {
WaitingSender,
WaitingReceiver,
Connected,
Expired,
}
Connection State
// WebRTC connection state
'new' โ 'connecting' โ 'connected' โ 'disconnected' | 'failed'
// DataChannel state
'connecting' โ 'open' โ 'closing' โ 'closed'
โก Performance Optimization
Backend Optimization
-
Async I/O
- Tokio async runtime
- Non-blocking WebSocket
- High concurrency support
-
Memory Management
- RwLock read-write lock
- Periodic cleanup of expired rooms
- Zero-copy message forwarding
-
Compile Optimization
[profile.release] opt-level = 3 lto = true codegen-units = 1
Frontend Optimization
-
Chunked Transfer
- 256KB chunk size
- Avoids memory overflow
- Real-time progress updates
-
Resource Optimization
- No framework dependencies
- Compressed icon resources
- CSS variable reuse
-
User Experience
- Toast instead of alert
- Smooth animations
- Responsive design
๐ Known Issues and Solutions
1. Connection Timing Issue
Problem: Sender creates offer too early, receiver not ready
Solution:
// Sender waits for peer-joined message
case 'peer-joined':
if (this.role === 'sender') {
this.createOffer();
}
break;
2. Room Premature Deletion
Problem: One party leaving causes room deletion, other cannot join
Solution:
// Remove is_empty() check, rely only on 1-hour expiration
pub async fn leave_room(&self, code: &str, role: Role) {
let mut rooms = self.rooms.write().await;
if let Some(room) = rooms.get_mut(code) {
room.remove_client(role);
// Do not delete room immediately
}
}
3. NAT Traversal
Problem: Symmetric NAT cannot establish P2P connection
Solution:
- Short-term: Use STUN server (already configured)
- Long-term: Integrate TURN server (relay)
๐ Performance Metrics
| Metric | Value |
|---|---|
| Backend binary size | < 2MB (release) |
| Frontend asset size | < 100KB (including icons) |
| Memory usage | < 10MB (idle) |
| Startup time | < 10ms |
| Concurrent rooms | 1000+ (depends on memory) |
| Transfer speed | 10-50 MB/s (LAN) |
๐ฎ Future Optimizations
Short-term (1-3 months)
- Add transfer speed display
- Support resumable transfers
- Add file preview
- Optimize large file transfers (streaming)
Medium-term (3-6 months)
- Integrate TURN server
- Add file encryption option
- Support batch transfer queue
- Mobile PWA optimization
Long-term (6-12 months)
- Text message transfer
- QR code sharing
- Transfer history (optional)
- Custom STUN/TURN configuration
๐ References
๐ค Design Principles
- Simplicity over complexity - Avoid over-engineering
- Performance over features - Keep it lightweight and efficient
- Security over convenience - Privacy first
- User experience over technical flair - Practicality-focused
Last updated: 2026-04-07