Isaac.

Using WebSockets for Real-Time Communication

Learn how to use WebSockets for real-time communication in web applications and ASP.NET Core.

By EMEPublished: February 20, 2025
aspnetwebsocketsreal-time communicationweb developmentnetwork protocols

A Simple Analogy

Imagine a phone call vs. sending letters. HTTP is like sending letters—you write one, mail it, and wait for a reply. WebSockets are like a phone call—once you connect, you can both talk instantly without waiting. The connection stays open so information flows both ways, whenever needed.


What Are WebSockets?

WebSockets is a communication protocol that provides a persistent, bi-directional connection between client and server over a single TCP connection. Unlike HTTP, which is request/response based, WebSockets allow both sides to send data at any time, making them perfect for real-time applications.


Why Use WebSockets?

  • Instant updates: Data flows immediately, not on request
  • Bi-directional: Server and client can both initiate communication
  • Low latency: No request/response overhead
  • Efficient: Single connection, not multiple HTTP requests
  • Real-time features: Chat, notifications, live dashboards, multiplayer games

How WebSockets Work

  1. Handshake: Client sends HTTP upgrade request to server
  2. Connection established: Server accepts, connection becomes WebSocket
  3. Data exchange: Both sides send and receive frames instantly
  4. Persistent: Connection stays open until closed

WebSocket in ASP.NET Core

Basic WebSocket Middleware

var app = builder.Build();

app.Use(async (context, next) => {
    if (context.Request.Path == "/ws")
    {
        if (context.WebSockets.IsWebSocketRequest)
        {
            WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
            await HandleWebSocket(context, webSocket);
        }
        else
        {
            context.Response.StatusCode = 400;
        }
    }
    else
    {
        await next();
    }
});

async Task HandleWebSocket(HttpContext context, WebSocket webSocket)
{
    byte[] buffer = new byte[1024 * 4];

    try
    {
        while (webSocket.State == WebSocketState.Open)
        {
            WebSocketReceiveResult result = await webSocket.ReceiveAsync(
                new ArraySegment<byte>(buffer), CancellationToken.None);

            if (result.MessageType == WebSocketMessageType.Text)
            {
                string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                await webSocket.SendAsync(
                    new ArraySegment<byte>(Encoding.UTF8.GetBytes($"Echo: {message}")),
                    WebSocketMessageType.Text, true, CancellationToken.None);
            }
        }
    }
    finally
    {
        webSocket.Dispose();
    }
}

app.Run();

Client-Side (JavaScript)

const ws = new WebSocket('ws://localhost:5000/ws');

// Connection opened
ws.onopen = () => {
    console.log('Connected');
    ws.send('Hello from client!');
};

// Receive messages
ws.onmessage = (event) => {
    console.log('Message from server:', event.data);
};

// Connection closed
ws.onclose = () => {
    console.log('Disconnected');
};

WebSockets with SignalR (Recommended)

SignalR wraps WebSockets and provides automatic fallbacks and higher-level abstractions:

builder.Services.AddSignalR();

app.MapHub<ChatHub>("/chatHub");

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

Practical Examples

  • Live chat: Instant messages between users
  • Multiplayer games: Real-time player positions and actions
  • Stock ticker: Live price updates without polling
  • Collaboration tools: Real-time document edits
  • Notifications: Push alerts instantly to users
  • Dashboards: Live metrics and analytics updates

Real-World Use Cases

  • Customer support chat systems
  • Online whiteboard and design tools
  • IoT device dashboards
  • Live sports or auction updates
  • Collaborative editing (Google Docs-like apps)
  • Online gaming platforms
  • Real-time notification systems

WebSockets vs. HTTP Polling vs. Server-Sent Events

| Feature | HTTP Polling | Server-Sent Events (SSE) | WebSockets | |---------|--------------|-------------------------|-----------| | Bi-directional | Client only | Server only | Both | | Overhead | High (many requests) | Low | Very low | | Complexity | Simple | Medium | Medium | | Browser support | Excellent | Good | Excellent | | Use case | Legacy | One-way updates | Real-time chat/games |


Best Practices

  • Use SignalR for most real-time needs (built-in fallbacks, easier)
  • Keep WebSocket messages small for performance
  • Implement proper error handling and reconnection logic
  • Monitor connection count for scaling
  • Use compression for large messages
  • Secure with SSL/TLS (wss:// not ws://)
  • Clean up connections on client disconnect
  • Rate limit to prevent abuse

Related Concepts to Explore

  • HTTP/2 and HTTP/3 (multiplexing, push)
  • Server-Sent Events (SSE) alternative
  • gRPC streaming (binary protocol)
  • Message protocols (JSON, MessagePack)
  • Connection pooling and scaling
  • Load balancing with WebSockets
  • WebSocket subprotocols
  • Event-driven architecture
  • Pub/Sub messaging patterns
  • Real-time monitoring and observability

Summary

WebSockets enable true real-time communication between clients and servers. By maintaining a persistent connection, they eliminate the polling overhead of HTTP and unlock instant, bi-directional data flow. Whether you use raw WebSockets or the higher-level SignalR abstraction, mastering WebSockets is essential for modern, interactive web applications.