Les notifications en temps réel sont devenues la pierre angulaire de la conception moderne d'applications Web. Les utilisateurs attendent des commentaires instantanés lorsque les événements surviennent : un nouveau message de chat arrive, un collègue approuve un document ou un déclencheur d'alerte serveur. Pour construire cette fonctionnalité dans une application Web JavaScript, il faut planifier soigneusement, utiliser les bons protocoles de communication et concevoir une interface utilisateur réfléchie.

Pourquoi les notifications en temps réel comptent-elles?

Les notifications en temps réel éliminent la nécessité de rafraîchir ou de procéder à des sondages manuels, ce qui draine la bande passante et dégrade l'expérience utilisateur. Lorsqu'un utilisateur reçoit une alerte instantanée, il reste engagé et peut réagir rapidement. Pour les plateformes SaaS, les outils de collaboration ou les tableaux de bord du commerce électronique, cette immédiateté a une incidence directe sur la productivité et la satisfaction.

Au-delà de l'expérience utilisateur, les notifications en temps réel permettent également de nouveaux modèles d'interaction : flux de commentaires en direct, curseurs d'édition collaborative et flux d'événements côté serveur.

WebSocket: Communication duplex

WebSockets fournit un canal bidirectionnel persistant entre un client et un serveur. Contrairement à HTTP, la connexion reste ouverte après la poignée de main initiale, permettant aux deux côtés de pousser les données à tout moment. Cela rend WebSockets idéal pour les applications de chat, les flux financiers en direct et les jeux multijoueurs — tout scénario où la basse latence, la messagerie bidirectionnelle est critique.

Établir une connexion WebSocket à JavaScript

L'API native du navigateur rend la configuration de la connexion simple. Vous introduisez un nouvel objet avec l'URL du serveur (en utilisant le schéma pour les connexions sécurisées). Ensuite, attachez les auditeurs d'événements pour , , et .

const socket = new WebSocket('wss://api.directus.app/websocket');

socket.onopen = () => {
 console.log('WebSocket connection established.');
 // Optionally send an authentication token
 socket.send(JSON.stringify({ type: 'auth', token: 'your-jwt' }));
};

socket.onmessage = (event) => {
 const data = JSON.parse(event.data);
 if (data.type === 'notification') {
 showToast(data.payload.message);
 }
};

socket.onerror = (err) => {
 console.error('WebSocket error:', err);
};

socket.onclose = (event) => {
 console.warn('WebSocket closed:', event.code, event.reason);
 // optional reconnect logic
};

Après avoir établi la connexion, vous pouvez envoyer des messages formatés JSON et gérer les réponses dans le gestionnaire . Le serveur doit prendre en charge le protocole WebSocket; de nombreux frameworks Node.js (p. ex. ], ) et des backends CMS comme Directus offrent une prise en charge WebSocket intégrée ou basée sur un plugin.

Manipulation de la reconnexion et des battements de cœur

Un système robuste en temps réel doit gérer les interruptions réseau avec grâce. Implémenter une stratégie de reconnection qui recule exponentiellement:

function connectWebSocket() {
 const socket = new WebSocket('wss://api.directus.app/websocket');
 let retryDelay = 1000;

 socket.onclose = () => {
 setTimeout(() => {
 console.log('Reconnecting...');
 connectWebSocket();
 }, retryDelay);
 retryDelay = Math.min(retryDelay * 2, 30000);
 };

 // ...other handlers
}

connectWebSocket();

De plus, envoyez des pings périodiques (toutes les 30 à 60 secondes) pour détecter les connexions statiques. De nombreuses bibliothèques WebSocket s'en occupent automatiquement, mais si vous utilisez l'API brute, définissez un intervalle pour envoyer un message et attendez une réponse .

Événements en service au serveur : plus simple, un seul temps de diffusion

Server-Sent Events (SSE) est une alternative légère lorsque vous n'avez besoin que du serveur pour pousser les données vers les clients sans exiger des messages client-to-server. SSE utilise HTTP standard; le serveur répond avec un en-tête et maintient la connexion ouverte. Le client lit le flux via l'API .

SSE est plus simple à implémenter que WebSockets, fonctionne sur HTTP/2, et se reconnecte automatiquement lorsque la connexion tombe. Cependant, il ne supporte pas la communication bidirectionnelle, donc il est le mieux adapté pour les flux d'informations, les sélecteurs de stock, ou les alertes système.

Utilisation de EventSource dans le navigateur

L'interface de browsers est minimale:

const eventSource = new EventSource('/api/events?user_id=42');

eventSource.onopen = () => {
 console.log('SSE connection opened.');
};

eventSource.addEventListener('notification', (event) => {
 const data = JSON.parse(event.data);
 displayNotification(data);
});

eventSource.onerror = (err) => {
 console.error('EventSource error:', err);
 // The browser will automatically attempt to reconnect
};

function displayNotification(data) {
 // Update UI
}

Du côté serveur, vous formatez chaque événement en lignes de texte:

event: notification
data: {"message":"Your report is ready","severity":"info"}

Notez que l'API ne prend en charge que les requêtes GET et ne peut pas envoyer d'en-têtes personnalisés. Si vous devez passer des jetons d'authentification, ajoutez-les en tant que paramètres de requête (utilisez HTTPS pour éviter d'exposer le jeton).

WebSocket vs. SSE: Choisir la bonne approche

Les deux technologies sont capables de traiter les notifications en temps réel, mais elles servent des cas d'utilisation différents:

Feature WebSocket SSE
Direction Bidirectional Server → Client only
Auto‑reconnect Must implement manually Built‑in
Binary data Yes (ArrayBuffer, Blob) Text only (UTF‑8)
Browser support Excellent (IE10+) Good (no IE/Edge Legacy)
Complexity Higher Lower

Si le client doit renvoyer des commandes ou des données au serveur (par exemple, en marquant une notification comme lue), WebSocket est le choix naturel. Pour les flux de notification simples, SSE réduit les frais de développement et est plus facile à déboguer parce qu'il utilise des en-têtes HTTP standard.

Intégration des notifications en temps réel avec Directus

Directus est un CMS sans tête qui expose une API REST et GraphQL. Pour ajouter des fonctionnalités en temps réel, vous pouvez utiliser son support WebSocket (introduit dans Directus 10.x) ou configurer un paramètre SSE via une extension personnalisée. L'API WebSocket vous permet de vous abonner à des modifications sur des collections spécifiques, ce qui rend simple de pousser les notifications lorsqu'un nouvel enregistrement est créé ou mis à jour.

Abonnement WebSocket en Directus

Directus WebSocket () accepte les messages JSON pour s'abonner, se désabonner ou s'authentifier. Par exemple, pour écouter de nouveaux messages dans une collection :

const ws = new WebSocket('wss://cms.example.com/websocket');

ws.onopen = () => {
 // Subscribe to changes on the notifications collection
 ws.send(JSON.stringify({
 type: 'subscribe',
 collection: 'notifications',
 query: { filter: { user_id: { _eq: currentUserId } } }
 }));
};

ws.onmessage = (event) => {
 const msg = JSON.parse(event.data);
 if (msg.type === 'subscription' && msg.event === 'create') {
 showNotification(msg.data);
 }
};

Cette approche décharge la complexité de la synchronisation en temps réel du CMS, tandis que votre application JavaScript n'a besoin que de gérer les données entrantes. Pour l'authentification, envoyez un jeton dans le premier message WebSocket (comme montré précédemment).

Affichage des notifications dans l'interface utilisateur

Une fois les données disponibles, l'expérience utilisateur dépend de la façon dont vous les présentez. Les notifications de toasts sont le motif le plus courant : un petit popup non intrusif qui apparaît au coin de l'écran et qui se libère automatiquement après quelques secondes. Des bibliothèques comme Toastr, Notyf[, ou Sonner fournissent des composants prêts à utiliser avec un balisage et une animation accessibles.

Ou bien, créez un composant de notification personnalisé. Voici un exemple minimal en utilisant le JavaScript et le CSS vanillés :

function showToast(message, type = 'info') {
 const toast = document.createElement('div');
 toast.className = `toast toast-${type}`;
 toast.textContent = message;
 toast.setAttribute('role', 'alert');
 document.getElementById('toast-container').appendChild(toast);

 setTimeout(() => toast.remove(), 3000);
}

// CSS (simplified):
.toast {
 padding: 12px 20px;
 margin-bottom: 8px;
 border-radius: 4px;
 color: #fff;
 opacity: 0.9;
 transition: opacity 0.3s;
}
.toast-info { background: #007bff; }
.toast-error { background: #dc3545; }
.toast-success { background: #28a745; }

Assurez-vous que le contenant est fixé au coin supérieur droit et que les toasts s'empilent verticalement. Utilisez sur le contenant pour s'assurer que les lecteurs d'écran annoncent de nouvelles notifications.

Préférences de l'utilisateur et gestion des notifications

Toutes les notifications ne sont pas également importantes. Permet aux utilisateurs de personnaliser les événements qu'ils veulent recevoir et par quels canaux (application, e-mail, push).Les préférences de stockage dans le moteur et les événements de filtre sur le serveur avant de les pousser vers le client. Par exemple, un utilisateur peut désactiver les alertes --nouveau commentaire - mais garder -task assignée--alertes.

Dans votre application JavaScript, procédez périodiquement à la recherche du profil de préférence de l'utilisateur et ajustez les filtres d'abonnement en conséquence. Si vous utilisez Directus WebSockets, vous pouvez envoyer une requête d'abonnement mise à jour lorsque les préférences changent.

Retour pour les navigateurs non pris en charge

Bien que les navigateurs modernes prennent en charge les serveurs Web et les SSE, les environnements plus anciens (p. ex. Internet Explorer 11 pour WebSockets, IE/Edge Legacy pour SSE) peuvent nécessiter des polyfills ou des stratégies de repli.

  • Appui de la démantelage avec ou .
  • Retard de Pollision: Utilisez un paramètre de Pollision Long qui renvoie de nouveaux événements sous JSON. Le client demande le paramètre toutes les quelques secondes et traite tout événement en attente.
  • Abrégé de la bibliothèque[: Utilisez une bibliothèque comme qui tombe de manière transparente de WebSocket à HTTP long-polling.

Lors du sondage, fixez un intervalle raisonnable (p. ex., 5-10 secondes) et retournez une réponse vide si aucun événement n'est en cours. Pour réduire la charge, utilisez des en-têtes ou des requêtes basées sur l'horodatage.

Considérations en matière de sécurité

Les connexions en temps réel introduisent plusieurs vecteurs de sécurité qui doivent être traités:

  • Authenticiate chaque connexion. Pour WebSockets, envoyez un jeton JWT ou session dans le premier message. Pour SSE, ajoutez un jeton comme paramètre de requête (mais jamais dans l'URL si vous le logez).
  • Valider et désinfecter toutes les données avant de les pousser vers le client. Même si votre moteur de recherche est fiable, ne jamais produire de contenu brut généré par l'utilisateur dans une notification sans s'échapper.
  • [, ]] pour prévenir les attaques de l'homme dans le milieu.
  • Les connexions de limite de taux[ par utilisateur pour prévenir les abus. Directus expose les paramètres de limitation de taux que vous pouvez configurer.
  • Ne pas exposer l'état du serveur interne par des messages WebSocket ou SSE. Toujours retourner uniquement les données que l'utilisateur est autorisé à voir.

Performance et scalabilité

À mesure que le nombre de connexions simultanées augmente, votre serveur doit les gérer efficacement. Considérez ces optimisations :

  • Utilisez un serveur WebSocket dédié (p. ex., processus node.js séparé) et étalez horizontalement avec un équilibreur de charge qui prend en charge les sessions collantes WebSocket.
  • Diffusion uniquement aux utilisateurs concernés. Utilisez des chambres ou des canaux basés sur l'ID de l'utilisateur, le groupe ou le filtre d'abonnement pour éviter d'envoyer chaque événement à chaque client.
  • Messages de compression.Pour les protocoles basés sur le texte, activez le dégonflage par message (WebSocket) ou gzip (SSE sur HTTP/2).
  • [Monitor connection health] avec des paramètres comme les connexions ouvertes, le débit de message et les taux d'erreur.
  • Consider server‐sent events caching. Avec SSE, vous pouvez utiliser les en-têtes HTTP si le flux est statique pendant une période (bien que les notifications soient généralement dynamiques).

Tout mettre en place : un flux de travail complet

Pour illustrer un exemple réel, let=s combine un moteur Directus avec un frontend JavaScript qui utilise SSE pour les notifications.

  1. Backend (Directus Extension):[ Créez un paramètre personnalisé à qui vérifie le jeton JWT de l'utilisateur, puis enchaîne les nouvelles notifications d'une file d'attente (par exemple, Redis pub/sub ou un crochet Directus qui écrit à une collection .
  2. Frontend: Sur la charge de page, authentifier avec Directus et ouvrir un pointant vers . Écoutez événements.
  3. Affichage:[ Chaque notification reçue est faite sous forme de toast à l'aide d'un composant personnalisé, avec des options pour rejeter ou ouvrir la ressource connexe.
  4. Préférences de l'utilisateur:[ Lorsque l'utilisateur met à jour ses paramètres de notification via un formulaire, envoyez un POST à Directus . Le moteur rafraîchit le filtre de flux d'événements pour cette session.

Cette architecture maintient le client en position assise et pousse le poids lourd à Directus et son système de crochet.

Essais de notifications en temps réel

Avant de déployer, testez soigneusement votre mise en œuvre :

  • Test de charge:[ Utiliser des outils comme Artillerie pour simuler des centaines de connexions WebSocket ou SSE simultanées. Mesurer la latence et la stabilité de connexion.
  • Grottling réseau:[ Utilisez Chrome DevTools pour simuler des conditions lentes 3G ou hors ligne. Vérifiez que la logique de reconnection fonctionne et qu'aucune notification dupliquée n'est envoyée.
  • Test de navigateur :[ Test dans Firefox, Safari, Chrome et Edge. Pour SSE, test dans Safari (qui manque de support complet EventSource pour les événements personnalisés – vous pouvez avoir besoin d'utiliser un polyfill).
  • Cas de bord de sécurité:[ Tentative de connexion avec des jetons expirés, ou injectez JSON mal formé pour s'assurer que vos gestionnaires d'erreur ne plantent pas le client.

Conclusion

Les notifications en temps réel ne sont plus un luxe, elles sont une attente de base dans les applications Web modernes. En tirant parti de WebSockets ou SSE, combiné avec un moteur comme Directus qui fournit des crochets en temps réel, vous pouvez fournir des mises à jour instantanées sans surcharger votre infrastructure.

Commencer petit : mettre en œuvre un simple toast pour un type d'événement, puis progressivement s'étendre à plusieurs canaux et préférences des utilisateurs. La clé est d'enclencher l'expérience utilisateur tout en maintenant le transport sous-jacent efficace et durable.