WebSocket in C#: Real-time Applications from A to Z

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why WebSocket is the Standard for Real-time Applications?



Modern web applications require instant response to user actions. Whether it's an online chat, a trading terminal, a multiplayer game, or a monitoring system — delays in data transmission are unacceptable. The traditional HTTP protocol, operating on a "request-response" principle, is inefficient for such scenarios: the client has to constantly poll the server, creating redundant load.



WebSocket comes to the rescue — a protocol that provides a persistent two-way connection between the client and server. In this article, we will explore how to create real-time applications in C# (.NET) using WebSocket, from a simple echo server to a full-fledged chat. You will learn how the protocol works, what tools the .NET platform offers, and how to avoid common mistakes.



WebSocket Basics in .NET: Server Side



The .NET platform offers built-in WebSocket support through the System.Net.WebSockets namespace. Let's look at creating a server based on ASP.NET Core.



1. Configuring WebSocket Middleware



First, you need to add WebSocket support to the request processing pipeline. In the Program.cs file:



var builder = WebApplication.CreateBuilder(args);var app = builder.Build();

app.UseWebSockets(); // Enable WebSocket support

app.Map("/ws", async (HttpContext context) =>{ if (context.WebSockets.IsWebSocketRequest) { using var webSocket = await context.WebSockets.AcceptWebSocketAsync(); await Echo(webSocket); } else { context.Response.StatusCode = 400; }});

app.Run("http://localhost:5000");

async Task Echo(WebSocket webSocket){ var buffer = new byte[1024 * 4]; var receiveResult = await webSocket.ReceiveAsync( new ArraySegment<byte>(buffer), CancellationToken.None);

while (!receiveResult.CloseStatus.HasValue) { // Send received data back to the client (echo) await webSocket.SendAsync( new ArraySegment<byte>(buffer, 0, receiveResult.Count), receiveResult.MessageType, receiveResult.EndOfMessage, CancellationToken.None);

receiveResult = await webSocket.ReceiveAsync( new ArraySegment<byte>(buffer), CancellationToken.None); }

await webSocket.CloseAsync( receiveResult.CloseStatus.Value, receiveResult.CloseStatusDescription, CancellationToken.None);}


This code creates an echo server: everything the client sends is returned back. Note the use of async/await — working with WebSocket is always asynchronous.



2. Managing Multiple Connections



In a real application, you need to manage multiple connections. Let's create a simple connection manager:



public class WebSocketConnectionManager{    private readonly ConcurrentDictionary<string, WebSocket> _connections = new();

public string AddConnection(WebSocket socket) { var id = Guid.NewGuid().ToString(); _connections.TryAdd(id, socket); return id; }

public async Task BroadcastMessageAsync(string message) { var tasks = _connections.Values.Select(async socket => { if (socket.State == WebSocketState.Open) { var bytes = Encoding.UTF8.GetBytes(message); await socket.SendAsync( new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, CancellationToken.None); } }); await Task.WhenAll(tasks); }}


This class allows you to store all active connections and broadcast messages

Blogs

Book Recommendations