Version du document 29/05/2026 · Objectif : l’unique VPS actuel doit tenir jusqu’à 100 000 MAU sans tomber, et l’application passer à un CDN sans couture le moment venu.
| Metric | Valeur | Source |
|---|---|---|
| MAU | 100,000 | l’objectif |
| DAU | 30,000 | 30 % du MAU, normal pour une application utilitaire |
| WS simultanés | 10 000 (pic 15 000) | ~10 % du MAU en journée, 15 % au pic |
| Actions par jour | 90,000 | 3 ouvertures ou appels par utilisateur quotidien |
| Requêtes de l’API HTTP par seconde (moyenne) | 3-5 | surtout key_create, host_sync et crash_report |
| Requêtes de l’API HTTP par seconde (pic) | 30-50 | après une publication massive qui met à jour les numéros |
count=1 — un unique processus PHP tient TOUTES les connexions WebSocket dans les tableaux $hosts, $guests, $calls in-memory.File: HostService.kt:1424-1432. Aujourd’hui syncPendingHostKeys() est appelée toutes les 60 s et frappe Api.keyCreate pour chaque clé en attente sans aucune attente.
Stocker dans Prefs per-localId: attempt_at_id et attempt_count_id. Attente : 30 s → 60 s → 2 min → 5 min → 15 min → 30 min (plafond). Remise à zéro en cas de succès.
File: Vault.kt:213. La même logique.
File: GuestConn.kt (5+ endroits). Comparer le nouveau parseNumbers avec le précédent, par hachage ou directement. S’ils sont identiques, ne pas incrémenter AppState.overridesVersion. Cela supprime les vagues de recomposition — 80 lectures de SharedPreferences × 20 cartes — à chaque initialisation WebSocket.
In server.php case 'host_hello' / 'guest_hello' : si le même device_id / user_key a envoyé un hello il y a moins de N secondes, fermer la connexion sans toucher la base. N = 5 s.
Protection au cas où un client à la logique cassée enverrait cent hellos par seconde.
In enqueueHostMsg : si ce host_id a déjà plus de 200 lignes, supprimer la plus ancienne avec DELETE FROM pending_host_msgs WHERE host_id=? ORDER BY id ASC LIMIT 1. Protection contre la croissance sans fin de la file en cas d’activité malveillante.
In _config.php:
$GLOBALS['apk_url'] = 'https://entrixy.com/entrixy.apk';
$GLOBALS['download_page_url'] = 'https://entrixy.com/download';
In api/version_check.php: 'download_url' => $GLOBALS['apk_url'].
Lors du passage au CDN, exactement une ligne changera dans _config.php to https://apk.entrixy.com/entrixy.apk (Cloudflare R2 avec un domaine personnalisé). Aucune publication d’application n’est requise.
Le client vérifie déjà la signature de l’APK au téléchargement (keystore de débogage, voir build.gradle.kts:23-29). Pour un CDN cela suffit : même si un nœud du CDN remplace le fichier, la signature ne correspondra pas et Android refusera de l’installer. Rien de plus n’est à faire côté client.
count=1 Workerman tient sans peine environ 10 000 WebSockets simultanés — server.php démarre déjà avec lui à la ligne 40. Le premier goulet sera le temps CPU de PHP au pic d’échange : 10 000 pongs par seconde plus les actions.
Today $hosts, $guests, $calls sont des tableaux en mémoire dans un seul processus. Pour lancer plusieurs processus, il faut les déplacer vers Redis :
Un message arrive sur le worker W1 alors que le destinataire est sur W2 — on le relaie par Redis pub/sub.
Effect: mise à l’échelle linéaire jusqu’au nombre de cœurs du VPS. Sur quatre cœurs, cela fait environ 40 000 simultanées.
Moins souple et sans Redis. Chaque utilisateur atterrit toujours sur le même worker. Mais cela casse quand l’expéditeur et le destinataire se retrouvent sur des workers différents.
entrixy.apk.apk.entrixy.com → le raccorder via le CDN Cloudflare._config.php change $apk_url vers la nouvelle.assembleRelease add r2 cp app-release.apk apk-bucket/entrixy.apk.