Architecture temps réel d'une application mobile
Quand nous avons conçu Poker Players Arena (PPA), notre application mobile communautaire premium dédiée aux joueurs de poker, une exigence revenait dans chaque réunion : tout devait se mettre à jour instantanément. Un classement qui change après une victoire, un chat qui s'anime en table finale, un statut « en ligne » qui apparaît dès qu'un joueur ouvre l'application : ce sont ces micro-réactions qui donnent à une communauté la sensation d'être vivante. Derrière cette fluidité apparente se cache une architecture temps réel exigeante, bâtie sur React Native (Expo) côté mobile et Supabase côté serveur. Dans cet article, nous ouvrons les coulisses de cette mécanique : ce que « temps réel » signifie vraiment, pourquoi c'est difficile, et les principes que nous appliquons pour tenir la promesse d'une expérience instantanée et fiable.
Le « temps réel », et pourquoi c'est plus dur qu'il n'y paraît
Le temps réel, c'est la capacité à propager un changement vers tous les écrans concernés en quelques dizaines de millisecondes, sans que l'utilisateur ait à rafraîchir quoi que ce soit. L'idée semble simple, mais elle se heurte à une réalité physique : une donnée modifiée à un endroit doit voyager jusqu'à des milliers d'appareils, chacun avec sa qualité de réseau, sa version de l'application et son état local. Synchroniser ces écrans, c'est gérer simultanément la latence, les déconnexions, les reconnexions et les conflits.
L'approche naïve consiste à interroger le serveur en boucle (le polling), par exemple toutes les deux secondes. Cette méthode est simple mais ruineuse : elle multiplie les requêtes inutiles, vide la batterie et reste toujours en retard sur l'événement réel. Nous avons donc retenu une logique inverse : ne plus demander « quoi de neuf ? » en permanence, mais laisser le serveur nous prévenir uniquement quand quelque chose change.
Abonnements temps réel : écouter plutôt que demander
C'est le rôle de Supabase Realtime, qui s'appuie sur des websockets : une connexion permanente, bidirectionnelle, ouverte entre l'application et le serveur. Plutôt que de répéter des requêtes, l'application s'abonne à un flux. Concrètement, nous écoutons les changements directement au niveau de la base de données PostgreSQL : dès qu'une ligne est insérée, modifiée ou supprimée dans une table (un nouveau message, un score actualisé, un joueur qui rejoint un tournoi), l'événement est poussé vers tous les abonnés concernés.
Ce modèle change tout. Il transforme une base de données « passive », que l'on interroge, en une source d'événements « active », qui diffuse. Pour le chat d'un tournoi, par exemple, chaque message inséré déclenche une diffusion immédiate vers les participants abonnés à ce canal, sans logique de rafraîchissement manuel. Nous décrivons plus en détail ces choix produit dans notre étude de cas Poker Players Arena.
La présence : savoir qui est en ligne
Une communauté vivante, c'est aussi voir qui est connecté. La présence répond à une question délicate : comment savoir, à un instant donné, quels joueurs sont réellement actifs ? Une simple colonne « en ligne » en base ne suffit pas, car une application peut se fermer brutalement, perdre le réseau ou passer en arrière-plan sans prévenir.
Supabase Realtime fournit un mécanisme de présence dédié, fondé sur l'état partagé d'un canal : chaque appareil annonce son arrivée, maintient sa connexion, et son départ est détecté automatiquement lorsque le websocket se ferme. Cela nous évite les « fantômes » (ces utilisateurs affichés comme connectés alors qu'ils sont partis depuis longtemps) et fiabilise les indicateurs de présence sans surcharger la base.
Limiter la charge : n'écouter que le strict nécessaire
Le piège du temps réel, c'est l'abondance. S'abonner à tout, tout le temps, pour tous les utilisateurs, c'est la garantie d'un serveur saturé et d'une application qui chauffe. Notre principe directeur est donc la sobriété des abonnements : un écran ne s'abonne qu'à ce dont il a besoin, exactement quand il en a besoin, et se désabonne dès qu'il disparaît.
Le chat de PPA illustre parfaitement cette discipline. Plutôt que de maintenir un chat ouvert pendant tout un tournoi, nous l'activons uniquement en table finale, lorsque la tension monte et que les échanges ont le plus de valeur. Ce choix a une double vertu :
- Côté expérience, il concentre la conversation au moment le plus fort, là où elle crée vraiment de l'émotion communautaire.
- Côté technique, il réduit drastiquement le nombre de canaux ouverts simultanément et la charge de diffusion, ce qui protège la performance globale et la facture d'infrastructure.
Ce raisonnement, nous l'appliquons partout : un classement n'écoute les mises à jour que lorsqu'il est affiché, un profil ne s'abonne aux changements qu'à l'ouverture de l'écran. Bien dimensionner ces flux fait partie intégrante de nos services de développement d'applications.
Gérer l'état mobile, la cohérence et l'optimistic UI
Recevoir des événements ne suffit pas : encore faut-il les fusionner proprement dans l'état de l'application. Côté mobile, nous maintenons un état local qui sert de source d'affichage immédiate, puis nous le réconcilions avec les événements temps réel et avec la base, qui reste la référence ultime. Trois principes guident ce travail :
- Cohérence des données : en cas de divergence entre l'état local et le serveur, c'est toujours la base qui tranche. À la reconnexion, nous resynchronisons l'état pour rattraper les événements manqués pendant une coupure réseau.
- Optimistic UI : pour que l'application paraisse instantanée, nous affichons souvent le résultat d'une action (l'envoi d'un message, un « like ») avant même la confirmation du serveur. Si le serveur infirme l'opération, nous annulons proprement la modification et informons l'utilisateur, plutôt que de le faire attendre.
- Idempotence : un même événement peut arriver deux fois (reconnexion, rejeu). Nous concevons les traitements pour qu'un doublon ne crée jamais deux messages ni ne fausse un score.
Cette rigueur sur l'état est ce qui distingue une démo séduisante d'une application réellement fiable en production. Nos choix sur React Native, qui rendent cette gestion possible côté client, sont détaillés dans notre article sur React Native.
Quand l'application est fermée : les notifications push
Le temps réel par websocket fonctionne tant que l'application est ouverte. Mais un joueur ne reste pas connecté en permanence. Pour le rappeler au bon moment (le début de son tournoi, l'atteinte de la table finale, une réaction à son profil), nous nous appuyons sur les notifications push. Elles prolongent la boucle d'engagement au-delà de la session active et ramènent l'utilisateur dans l'application précisément quand quelque chose d'important se produit.
L'enjeu est de viser juste : une notification pertinente renforce la communauté, une notification de trop fait fuir. Nous traitons cet équilibre comme une discipline à part entière, abordée dans notre article notifications push et engagement.
Conclusion
L'architecture temps réel n'est pas une fonctionnalité que l'on coche : c'est un ensemble de principes (abonnements sobres, présence fiable, cohérence stricte, optimistic UI maîtrisée, push pertinent) qui, mis bout à bout, créent cette sensation d'application vivante. Sur Poker Players Arena, chaque décision a visé le même objectif : la réactivité au service de la communauté, jamais au détriment de la stabilité. Si vous portez un projet d'application communautaire ou temps réel et souhaitez en parler avec une équipe qui l'a déjà construit, contactez-nous : nous serons ravis d'en discuter.