backend
Ce qu'un client a manqué pendant son absence
Ce qu'un client a manqué pendant son absence
Socket.io brut te donne une connexion, des rooms, et emit/on. Il ne te donne rien sur le trou. Un client qui tombe brièvement et se reconnecte reprend juste la réception de nouveaux événements à partir de ce moment — tout ce qui a été émis pendant la coupure est parti, sans signal que ça a jamais eu lieu.
Pour une application de chat, ça va. Pour un tableau de file en direct ou le flux de tickets d'un opérateur de comptoir, ce trou silencieux est un écran périmé sans aucune indication que quelque chose ne va pas, posé dans une salle d'attente que personne ne surveille moment par moment.
Des numéros de séquence, pas des horodatages
Chaque événement émis dans une room reçoit un numéro de séquence qui augmente de façon monotone. Pas un horodatage — les horodatages peuvent entrer en collision ou tromper sous dérive d'horloge, un compteur non. Le serveur garde un tampon glissant des événements récents par room, chacun étiqueté.
queueEvent(room: string, event: string, payload: any) {
this.sequenceNumber++;
this.eventQueue.push({
room, event, payload,
sequence: this.sequenceNumber,
timestamp: Date.now(),
});
}
À la reconnexion, le client rapporte le dernier numéro de séquence qu'il a traité. Le serveur rejoue tout ce qui est supérieur, puis reprend le flux en direct. Si le trou est plus grand que ce que le tampon peut représenter en sécurité, le bon geste est de dire au client de récupérer un instantané frais plutôt que de renvoyer un rejeu partiel et trompeur.
Trois choses que j'aurais manquées
- Le tampon a besoin d'une taille max et d'un âge max, nettoyé à intervalle. Non borné, c'est une fuite de mémoire lente sur un service de longue durée. La taille seule ou l'âge seul manquent chacun un cas que l'autre attrape.
- L'autorisation doit être re-vérifiée sur le chemin de rejeu. Il est facile d'autoriser un client quand il rejoint une room et d'oublier que le rejeu est un second chemin par lequel les mêmes données passent. Saute la vérification là et c'est un contournement net de l'authentification cadrée sur la room que tu as imposée correctement partout ailleurs.
- Un client peut avoir l'air connecté au niveau transport tout en étant figé — un onglet mort, un appareil qui a perdu l'alimentation sans fermeture propre. Un ping/pong périodique avec un timeout l'attrape : pas de réponse dans la fenêtre, traite-le comme déconnecté et nettoie, même si le socket brut n'a jamais déclenché son propre
disconnect.
Combien de tout ça vaut la peine dépend de à quel point un écran est sans surveillance et à quel point un écran périmé est lourd de conséquences. Un onglet que quelqu'un regarde se reconnecte vite et le trou est invisible. Une borne qui tourne sans surveillance pendant des heures est un risque vraiment différent.