Pourquoi votre site ne « parle »-t-il pas encore à l'utilisateur en temps réel ?
\n\nImaginez : vous ouvrez un terminal boursier, et le taux du dollar se met à jour tout seul. Ou vous accédez à l'interface d'administration — et vous voyez le nombre d'utilisateurs inscrits augmenter sous vos yeux. Ou un chat où les messages arrivent sans « rafraîchissements » constants de la page.
\n\nAvant, pour cela, il fallait soit mettre en place WebSocket (complexe, coûteux, pas toujours nécessaire), soit utiliser le long polling (un bricolage qui épuise la batterie du téléphone). Mais il existe une troisième voie — les Server-Sent Events en C#.
\n\nAujourd'hui, nous allons décortiquer une technologie qui permet au serveur de « frapper » lui-même à la porte du client et de transmettre des données. Sans code superflu, sans tonnes de JavaScript, sans maux de tête avec les serveurs proxy. Que du C#, que du costaud.
\n\nQue sont les Server-Sent Events (SSE) et pourquoi ce n'est pas un « protocole pour les pauvres »
\n\nServer-Sent Events (ou SSE) est un standard HTML5 qui permet au serveur d'envoyer des données en continu au client via une connexion HTTP ordinaire. Le client s'abonne aux événements, et le serveur écrit simplement dans Response.Body. C'est tout.
\n\nLa principale différence avec WebSocket : SSE est un canal unidirectionnel (serveur → client). Vous n'avez pas besoin d'envoyer des données en retour ? Parfait, SSE est fait pour vous. De plus :
\n\n- \n
- Fonctionne sur HTTP/1.1 et HTTP/2 standard \n
- Se reconnecte automatiquement en cas de coupure (intégré dans l'
EventSourcedu navigateur) \n - Ne nécessite pas de bibliothèques supplémentaires côté client (à part le JavaScript standard) \n
- Passe à travers tous les proxys et équilibreurs de charge (contrairement à WebSocket) \n
En pratique, SSE C# est utilisé pour :
\n- \n
- Les flux de notifications (notifications push directement dans le navigateur) \n
- La surveillance de serveurs (tableaux de bord avec métriques en direct) \n
- La diffusion de logs (par exemple, tail -f dans le navigateur) \n
- Le streaming de générations AI (distribution progressive des réponses des modèles de type ChatGPT) \n
Comment fonctionne SSE : le protocole en une ligne
\n\nTout ce qui est génial est simple. Le serveur envoie au client un flux de texte avec un format spécial :
\n\ndata: Bonjour le monde !\\n\\n\ndata: {"message": "Le JSON fonctionne aussi"}\\n\\n\nevent: customEvent\\n\ndata: Événement nommé\\n\\n\n\nChaque message commence par data:, se termine par deux retours à la ligne. Vous pouvez spécifier event: pour un type d'événement personnalisé, id: pour un identifiant et retry: pour le délai de reconnexion.
Le client en JavaScript s'abonne ainsi :
\n\nconst source = new EventSource("/api/stream");\nsource.onmessage = (event) => {\n console.log("Reçu :", event.data);\n};\nsource.addEventListener("customEvent", (event) => {\n console.log("Événement personnalisé :", event.data);\n});\n\nEt cela fonctionne dans tous les navigateurs modernes. Pas de paquets npm, pas de polyfills WebSocket.
\n\nServer-Sent Events en C# : Implémentation sur ASP.NET Core
\n\nÉcrivons enfin le code. La façon la plus simple d'organiser les SSE en C# est de créer un point de terminaison (endpoint) dans ASP.NET Core qui ne termine pas la réponse, mais y écrit par morceaux.
\n\nEndpoint SSE de base
\n\nusing Microsoft.AspNetCore.Mvc;\n\n[ApiController]\n[Route("api")]\npublic class StreamController : ControllerBase\n{\n [HttpGet("stream")]\n public async Task Get(CancellationToken cancellationToken)\n {\n Response.Headers.Append("Content-Type", "text/event-stream");\n Response.Headers.Append("Cache-Control", "no-cache");\n Response.Headers.Append("Connection", "keep-alive");\n\n for (int i = 0; i < 10; i++)\n {\n if (cancellationToken.IsCancellationRequested)\n break;\n\n // Format SSE : data: ... \\n\\n\n await Response.WriteAsync($"data: Message #{i}\\n\\n",