Some checks failed
Build & Deploy / build-and-deploy (push) Failing after 8s
Includes React PWA frontend, WebSocket signaling server, shared types, K8s manifests, Gitea CI/CD workflow, nginx config, and Dockerfiles. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
88 lines
4.3 KiB
Markdown
88 lines
4.3 KiB
Markdown
# Architecture AnyDrop
|
|
|
|
## Vue d'ensemble
|
|
|
|
AnyDrop repose sur trois briques :
|
|
|
|
1. **Client** (web, extension, desktop, mobile) — interface utilisateur + moteur WebRTC
|
|
2. **Serveur de signaling** — met en relation les pairs, ne voit jamais les fichiers
|
|
3. **Serveurs STUN/TURN** — aident à établir la connexion P2P à travers les NAT/firewalls
|
|
|
|
```
|
|
┌──────────┐ WebSocket ┌────────────────┐ WebSocket ┌──────────┐
|
|
│ Client A │ ────────────────────▶ │ Signaling │ ◀──────────────────── │ Client B │
|
|
└──────────┘ │ Server │ └──────────┘
|
|
│ └────────────────┘ │
|
|
│ │
|
|
│ ═══════ WebRTC DataChannel (P2P chiffré DTLS) ═══════ │
|
|
└─────────────────────────────────────────────────────────────────────────────┘
|
|
(les fichiers transitent uniquement ici)
|
|
```
|
|
|
|
## Le serveur de signaling
|
|
|
|
### Responsabilités
|
|
|
|
- Accepter les connexions WebSocket entrantes
|
|
- Attribuer un `peerId` unique et un `displayName` (nom animal aléatoire) à chaque client
|
|
- Placer le client dans la ou les rooms appropriées :
|
|
- Room **LAN** : hash de l'IP publique de la connexion
|
|
- Room **publique** : code court fourni dans l'URL (ex: `/x7k`)
|
|
- Relayer les messages de signaling (`offer`, `answer`, `ice-candidate`) entre pairs d'une même room
|
|
- Notifier `peer-joined` / `peer-left`
|
|
- Expirer les rooms publiques inactives (10 min)
|
|
|
|
### Ce que le serveur ne fait PAS
|
|
|
|
- ❌ Ne stocke aucun fichier ni contenu échangé
|
|
- ❌ Ne log pas les IPs dans des fichiers persistants
|
|
- ❌ N'a pas de base de données
|
|
- ❌ N'a pas d'authentification
|
|
|
|
## Les clients
|
|
|
|
Tous les clients (web, extensions, desktop, mobile) implémentent le **même protocole de signaling** et la même logique WebRTC. Le code `shared/` exporte les types de messages communs pour garantir la cohérence.
|
|
|
|
### Couche abstraction P2P
|
|
|
|
On utilise `simple-peer` pour masquer la complexité de l'API WebRTC native :
|
|
|
|
```ts
|
|
const peer = new SimplePeer({ initiator: true, trickle: true });
|
|
peer.on('signal', data => sendViaWebSocket(data)); // envoyer offer/ICE
|
|
peer.on('connect', () => sendFile(file)); // connexion établie
|
|
peer.on('data', chunk => reassemble(chunk)); // chunks reçus
|
|
```
|
|
|
|
### Découpage des fichiers
|
|
|
|
- Chunk size : **16 Ko** (compromis débit/mémoire)
|
|
- Header JSON initial : `{ name, size, mime, id }`
|
|
- Puis envoi séquentiel avec backpressure (`peer._channel.bufferedAmount < 1MB`)
|
|
- Fin de fichier : chunk spécial `{ eof: true, id }`
|
|
- Récepteur : accumule dans un `Blob[]` puis `new Blob(chunks, { type })`
|
|
|
|
## STUN et TURN
|
|
|
|
### STUN (Session Traversal Utilities for NAT)
|
|
|
|
Gratuit, quasi-gratuit en bande passante (quelques paquets). Sert uniquement à ce que le client découvre sa propre IP publique + port NAT, pour l'inclure dans les ICE candidates.
|
|
|
|
Serveurs utilisés : `stun.l.google.com:19302`, `stun1.l.google.com:19302`.
|
|
|
|
### TURN (Traversal Using Relays around NAT)
|
|
|
|
Fallback quand le P2P direct échoue (~10-20% des cas, surtout en entreprise / 4G). Le trafic est alors **relayé** par le serveur TURN → coût bande passante réel.
|
|
|
|
- V1 : Open Relay (gratuit, 500 Go/mois) — suffisant pour un lancement
|
|
- Plus tard : coturn auto-hébergé sur un VPS
|
|
|
|
## Déploiement cible
|
|
|
|
| Composant | Hébergement | URL |
|
|
|----------------|----------------------|-----------------------------------|
|
|
| Front web (PWA)| Vercel / Netlify | `anydrop.arthurbarre.fr` |
|
|
| Signaling | Railway / Fly.io | `ws.anydrop.arthurbarre.fr` |
|
|
| STUN | Google (gratuit) | `stun.l.google.com:19302` |
|
|
| TURN | Open Relay → coturn | `turn.anydrop.arthurbarre.fr` |
|