WebSocket en C# : création d'applications temps réel dans .NET
Les applications web modernes exigent de plus en plus souvent un transfert instantané de données entre le client et le serveur. Le protocole HTTP traditionnel, fonctionnant selon le schéma « requête-réponse », n'est pas toujours efficace pour les tâches où la fréquence et la vitesse des mises à jour sont importantes — chats, jeux en ligne, cotations boursières, systèmes de surveillance. C'est là que le protocole WebSocket vient à la rescousse, en établissant une connexion bidirectionnelle permanente. Dans cet article, nous allons détailler comment implémenter WebSocket en C# (.NET), créer un serveur et un client complets, et examiner les meilleures pratiques.
Qu'est-ce que WebSocket et pourquoi en a-t-on besoin dans .NET ?
WebSocket est un protocole fonctionnant au-dessus de TCP, qui assure une communication full-duplex. Après l'établissement de la connexion via une poignée de main HTTP (handshake), les données peuvent être transmises dans les deux sens sans frais supplémentaires. Contrairement au Long Polling ou aux Server-Sent Events, WebSocket offre une latence minimale et un faible trafic.
Dans l'écosystème .NET, il existe deux approches principales pour travailler avec le temps réel :
- WebSocket natif (System.Net.WebSockets) — une API de bas niveau disponible dans ASP.NET Core. Donne un contrôle total sur la connexion, adapté aux protocoles personnalisés.
- SignalR — une bibliothèque de haut niveau de Microsoft, qui abstrait WebSocket et choisit automatiquement le transport (WebSocket, SSE, Long Polling). Idéale pour les tâches typiques (chats, notifications).
Le choix dépend de la tâche : si vous avez besoin d'un contrôle et de performances maximales — utilisez WebSocket natif ; si la rapidité de développement et la simplicité sont prioritaires — utilisez SignalR.
Création d'un serveur WebSocket en C# (ASP.NET Core)
Examinons une implémentation étape par étape du serveur. Pour commencer, créons un projet ASP.NET Core (modèle vide ou Web API).
Étape 1 : Configuration du Middleware
Ajoutez la prise en charge de WebSocket dans la méthode Configure du fichier Program.cs :
var builder = WebApplication.CreateBuilder(args);var app = builder.Build();
app.UseWebSockets(); // Active la prise en charge de WebSocket
app.Map("/ws", async (HttpContext context) =>{ if (context.WebSockets.IsWebSocketRequest) { using var webSocket = await context.WebSockets.AcceptWebSocketAsync(); await HandleWebSocketConnection(webSocket); } else { context.Response.StatusCode = 400; }});
app.Run();
async Task HandleWebSocketConnection(WebSocket webSocket){ var buffer = new byte[1024 * 4]; while (webSocket.State == WebSocketState.Open) { var result = await webSocket.ReceiveAsync( new ArraySegment<byte>(buffer), CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Close) { await webSocket.CloseAsync( WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None); } else if (result.MessageType == WebSocketMessageType.Text) { var message = Encoding.UTF8.GetString(buffer, 0, result.Count); Console.WriteLine($"Reçu : {message}");
// Réponse écho var response = Encoding.UTF8.GetBytes($"Écho : {message}"); await webSocket.SendAsync( new ArraySegment<byte>(response), WebSocketMessageType.Text, true, CancellationToken.None); } }}Ce code crée un serveur d'écho : il reçoit les messages texte et les renvoie avec le préfixe "Écho :". Notez la gestion de l'état de la connexion et le traitement de la fermeture.
Étape 2 : Gestion des connexions multiples
Dans une application réelle, il est nécessaire de stocker une liste des connexions actives. Utilisez ConcurrentDictionary ou ConcurrentBag :
public class WebSoc