Working with WebSockets in C# And .NET

In this post, we explore what WebSockets are, how they work, how they differ from HTTP, and how to implement them in a C# application.

Working with WebSockets in C# And .NET

Getting Started

WebSockets offer a powerful, bi-directional communication protocol ideal for real-time communication in modern applications like chat apps, multiplayer games, live dashboards, and notifications.

What is a WebSocket?

WebSocket is a communication protocol that provides full-duplex communication channels over a single, long-lived TCP connection. Unlike HTTP, which is request-response-based, WebSocket allows continuous data exchange between client and server.

Key Features:
  • Low Latency: Eliminates HTTP overhead
  • Persistent Connection: Only one handshake; no repeated headers
  • Bi-directional Communication: Server and client can send data at any time
  • Ideal for Real-Time Apps: Chat, gaming, notifications, stock tickers

Integrating WebSockets in C# (.NET)

Integrating WebSockets in a C# (.NET) application can be done in several ways depending on the type of application you're building, such as an ASP.NET Core Web API, a console app, or a WPF/WinForms client.

Below is a guide for setting up WebSocket support in ASP.NET Core (Server-side) and a basic WebSocket client in C#. You can create WebSocket servers and clients using built-in libraries System.Net.WebSockets

Creating a WebSocket Server in ASP.NET Core
In Setup.cs or Setup.cs
 using System.Net.WebSockets;  
 var builder = WebApplication.CreateBuilder(args);  
 var app = builder.Build();  
 // Enable WebSockets  
 var webSocketOptions = new WebSocketOptions  
 {  
   KeepAliveInterval = TimeSpan.FromSeconds(120)  
 };  
 app.UseWebSockets(webSocketOptions);  
 // Handle WebSocket requests  
 app.Map("/ws", async context =>  
 {  
   if (context.WebSockets.IsWebSocketRequest)  
   {  
     using var webSocket = await context.WebSockets.AcceptWebSocketAsync();  
     await Echo(context, webSocket);  
   }  
   else  
   {  
     context.Response.StatusCode = 400;  
   }  
 });  
 app.Run();  
 static async Task Echo(HttpContext context, WebSocket webSocket)  
 {  
   var buffer = new byte[1024 * 4];  
   WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);  
   while (!result.CloseStatus.HasValue)  
   {  
     await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count),  
                  result.MessageType,  
                  result.EndOfMessage,  
                  CancellationToken.None);  
     result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);  
   }  
   await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);  
 }  

Creating a WebSocket Client in C# Console App
 using System.Net.WebSockets;  
 using System.Text;  
 class Program  
 {  
   static async Task Main(string[] args)  
   {  
     using var client = new ClientWebSocket();  
     Uri serverUri = new Uri("ws://localhost:5000/ws");  
     try  
     {  
       await client.ConnectAsync(serverUri, CancellationToken.None);  
       Console.WriteLine("Connected to server");  
       var sendBuffer = Encoding.UTF8.GetBytes("Hello from client!");  
       await client.SendAsync(new ArraySegment<byte>(sendBuffer),  
                   WebSocketMessageType.Text,  
                   endOfMessage: true,  
                   CancellationToken.None);  
       var receiveBuffer = new byte[1024];  
       var result = await client.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);  
       string message = Encoding.UTF8.GetString(receiveBuffer, 0, result.Count);  
       Console.WriteLine($"Received from server: {message}");  
       await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "Done", CancellationToken.None);  
     }  
     catch (Exception ex)  
     {  
       Console.WriteLine($"Exception: {ex.Message}");  
     }  
   }  
 }  

How WebSockets Work

WebSockets are a communication protocol that allows two-way, interactive communication between a client (usually a web browser) and a server over a single, long-lived connection.

  1. Handshake
    • Client initiates a WebSocket connection via HTTP
    • Server agrees and upgrades the connection from HTTP to WebSocket.
  2. Open WebSocket Connection
    • Both client and server now maintain a persistent TCP connection.
    • Either side can send messages at any time (no need to wait for a request).
  3. Message Framing
    • Data is sent in frames (small data packets).
    • Frames can contain text, binary data, or control messages, such as pings, to check if the connection is alive.
    • This method is much faster and lighter compared to HTTP requests.
  4. Connection Closing
    • Either client or server can initiate a connection close.
    • A close frame is sent, optionally with a reason.
    • The other party acknowledges and the connection is closed.

How a Websocket is Diffrent from HTTP?

Both WebSocket and HTTP are fundamentally different in how they handle communication between a client and a server, although they are both communication protocols used on the web.

Here’s a breakdown of how WebSocket differs from HTTP:
  1. Connection Type
    • HTTP:
      • Stateless and one-way (request-response).
      • Client sends a request → server sends back a response → connection is closed.
      • For each new request, a new connection is typically established.
    • Websocket:
      • Stateful and full-duplex (two-way).
      • A single connection is established and kept open.
      • Both client and server can send messages at any time without re-establishing a connection.
  2. Communication Style
    • HTTP:
      • One-directional: Client → Server → Client.
      • The server cannot send data to the client unless the client first makes a request (polling or long-polling).
    • Websocket:
      • Bi-directional and real-time.
      • Either side can initiate communication at any time over the open connection.
  3. Connection Lifecycle
    • HTTP:
      • Short-lived.
      • Each interaction is independent of others.
    • Websocket:
      • Long-lived.
      • Connection stays open until explicitly closed.
  4. Protocol Details
    • HTTP:
      • Operates over TCP, usually on port 80 (HTTP) or 443 (HTTPS).
      • Text-based protocol (headers, verbs like GET/POST).
    • Websocket:
      • Also uses TCP, typically over port 80 or 443, but with a different protocol after the handshake.
      • Starts with an HTTP handshake, then "upgrades" the connection to WebSocket.
      • Binary or text frames (efficient for real-time).
  5. Use Cases
    • HTTP:
      • Traditional web pages, REST APIs, loading resources (HTML, CSS, images).
      • Good for request-response operations.
    • Websocket:
      • Real-time apps: chat, live notifications, gaming, collaborative tools.
      • Efficient for high-frequency or low-latency updates.
  6. Overhead & Performance
    • HTTP:
      • Higher overhead due to repeated handshakes.
      • Less efficient for frequent or small data transfers.
    • Websocket:
      • Lower overhead once connected./li>
      • More efficient for continuous or real-time data.
  7. Security: both are using secure TLS

Key Features of WebSockets

Here are the key features of WebSockets, which distinguish it from traditional HTTP-based communication:
  • Full-Duplex Communication: Allows bi-directional communication between client and server over a single, long-lived connection.
  • Low Latency: WebSockets eliminate the overhead of HTTP headers. No need to establish a new TCP connection for each request/response
  • Persistent Connection: After the initial HTTP handshake, the WebSocket connection stays open, allowing ongoing communication without repeated re-authentication or setup.
  • Event-Driven: Based on an event-driven model, where messages are triggered and handled through events like onopen, onmessage, onclose, and onerror.
  • Single TCP Connection: Uses one TCP connection for all communication, reducing resource usage and making it more efficient for applications with many users (e.g., chat apps, real-time dashboards).
  • Supports Security (WSS): WebSockets support TLS encryption via the wss:// protocol (secure WebSocket), ensuring secure data transmission over HTTPS.
  • Cross-Platform and Cross-Browser: Supported by most modern web browsers and works across platforms, making it ideal for real-time web applications.
  • Lightweight Protocol Overhead: After the initial handshake, WebSockets have a very lightweight framing protocol, minimizing the data overhead per message.

Benefits of Using WebSockets

  • Enables instant data transfer between client and server without polling or waiting.
  • Ideal for applications that need low-latency updates like chat apps, live trading platforms, and online games.
  • Supports true interactive communication.
  • WebSockets have minimal framing and don't require HTTP headers with each message.
  • No need for constant HTTP requests (polling or long-polling), which saves CPU, memory, and bandwidth.
  • With WSS (WebSocket Secure) over TLS, data is encrypted similarly to HTTPS, ensuring privacy and integrity.
  • Due to persistent and efficient data transfer, WebSockets are great for resource-constrained environments like mobile devices and IoT systems.
  • Natively supported in all modern web browsers via the WebSocket API, simplifying integration with frontend applications.

Limitations of WebSockets

Here are the key limitations of WebSockets that developers should consider when deciding to use them:
  • Some older proxies, firewalls, and enterprise networks may block or interfere with WebSocket traffic.
  • It can cause issues with transparent proxies or strict network configurations as WebSockets use non-standard ports (like 80/443 but with non-HTTP data).
  • If a connection drops, WebSockets don't automatically reconnect.
  • WebSocket protocol does not guarantee message delivery.
  • Scaling is more complicated as it is stateful connection
  • WebSocket applications often require more complex server and client-side logic compared to RESTful APIs.

Summary

Here, we learned how to work with WebSockets in C# using .NET, covering both server-side and client-side implementations. We also explored what WebSockets are, how they work, and their merits and demerits. I hope it was helpful to you.

Thanks

Kailash Chandra Behera

I am an IT professional with over 13 years of experience in the full software development life cycle for Windows, services, and web-based applications using Microsoft .NET technologies.

Previous Post Next Post

نموذج الاتصال