Why WebSockets Are Magic You Must Try
\n\nImagine: you opened a website with cryptocurrency rates. Prices jump every second. Or an online chat where messages arrive instantly, without "refresh the page". How does it work? Previously, the browser constantly poked the server: "Hey, is there anything new?" — and the server replied: "No, go to sleep." This is called HTTP polling. It is slow, consumes traffic, and loads the server.
\n\nWebSockets are like an open communication channel. The server itself can tell the client: "Look, an update!" — without unnecessary requests. In C#, working with WebSockets is not just convenient, but elegant. The .NET ecosystem provides ready-made tools: from native classes System.Net.WebSockets to the powerful SignalR.
In this article, we will not just talk about theory. We will write two real projects: a real-time chat and a stock market monitor. You will see how to create a WebSocket server C# and connect a client to it. Let's go!
\n\nWhat Are WebSockets and Why C# Is the Ideal Choice
\n\nWebSocket is a bidirectional communication protocol over TCP. After the handshake, the connection remains open. Data flies in both directions without HTTP headers. This provides:
\n\n- \n
- Speed — latency in milliseconds. \n
- Resource savings — one connection instead of hundreds of requests. \n
- True real-time — the server itself initiates sending. \n
C# in this context is a real heavy hitter. ASP.NET Core supports WebSockets out of the box. Plus asynchronous programming (async/await) fits perfectly with the channel work model. You do not block the thread while waiting for a message — this makes the code performant and readable.
\n\nFirst Project: Real-Time Chat on WebSockets
\n\nLet's start with a classic — a chat. It clearly demonstrates the entire mechanics: connection, sending, receiving, and closing the connection.
\n\nStep 1: Create a WebSocket Server in C#
\n\nOpen Visual Studio or a terminal. Create a new ASP.NET Core Web API (or empty) project. Install the package if needed:
\n\ndotnet add package Microsoft.AspNetCore.WebSockets\n\nNow in Program.cs we configure the middleware. Here is the minimal server code:
var builder = WebApplication.CreateBuilder(args);\nbuilder.Services.AddWebSockets(options => { });\nvar app = builder.Build();\n\napp.UseWebSockets();\n\n// List to store all connected clients\nvar clients = new List<System.Net.WebSockets.WebSocket>();\n\napp.Map("/chat", async (HttpContext context) =>\n{\n if (context.WebSockets.IsWebSocketRequest)\n {\n var webSocket = await context.WebSockets.AcceptWebSocketAsync();\n clients.Add(webSocket);\n Console.WriteLine("New client connected!");\n\n // Buffer for receiving data\n var buffer = new byte[1024 * 4];\n while (webSocket.State == WebSocketState.Open)\n {\n var result = await webSocket.ReceiveAsync(\n new ArraySegment<byte>(buffer), CancellationToken.None);\n \n if (result.MessageType == WebSocketMessageType.Close)\n {\n await webSocket.CloseAsync(\n WebSocketCloseStatus.NormalClosure, \n "Connection closed", CancellationToken.None);\n clients.Remove(webSocket);\n Console.WriteLine("Client disconnected.");\n }\n else if (result.MessageType == WebSocketMessageType.Text)\n {\n // Get message from one client\n var message = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count);\n Console.WriteLine($"Received: {message}");\n\n // Broadcast to everyone else\n v