Skip to main content

WebSockets

What It Is

WebSocket is a communication technique that creates a persistent, full-duplex connection between the client and the server.

After the connection is created, both client and server can send data anytime without creating new HTTP requests again and again.

WebSocket = One open connection + two-way real-time communication

Simple Example

Think of WebSocket like a phone call.

You connect once
Both sides can talk anytime
No need to reconnect repeatedly

This is different from polling, where the client has to keep asking the server for updates.


How Connection Is Established

A WebSocket connection starts as a normal HTTP request.

Then the connection is upgraded from HTTP to WebSocket.

HTTP request -> Upgrade request -> WebSocket connection

After the upgrade, the connection stays open.


HTTP Upgrade

The client sends an HTTP request asking the server to upgrade the connection.

GET /socket.io/?EIO=4&transport=websocket HTTP/1.1
Connection: Upgrade
Upgrade: websocket

The server responds with:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade

After this, the connection is no longer a normal request-response HTTP connection.

It becomes a persistent WebSocket connection.


What Upgrade Means

Normal HTTP works like this:

Request -> Response -> Close

WebSocket works like this:

Open connection -> Continuous communication -> Close connection

The key difference is that WebSocket does not need a new request for every message.


How It Works After Connection

Once the WebSocket connection is open:

1. Client connects once
2. Connection remains open
3. Client can send data anytime
4. Server can send data anytime
5. No repeated HTTP requests are required

This makes WebSocket useful for real-time applications.


Flow Diagram

Client                                      Server
| |
| ---- Handshake / HTTP Upgrade ----------> |
| |
| <---- Connection Opened ----------------- |
| |
| <========== Bidirectional Messages =====> |
| |
| ---- Message ---------------------------> |
| |
| <---- Message --------------------------- |
| |
| <---------- Connection Closed ----------> |

How Socket.IO Code Fits

In Socket.IO, the server listens for new connections.

const io = new Server(server);

io.on("connection", (socket) => {
socket.emit("chat-message", msg);
io.emit("chat-message", msg);
});

What this means:

CodeMeaning
new Server(server)Creates a Socket.IO server
io.on("connection")Runs when a client connects
socket.emit()Sends message to one connected client
io.emit()Sends message to all connected clients

Advantages

WebSockets are useful when the app needs fast and continuous updates.

AdvantageMeaning
Real-time communicationData can be sent instantly
No repeated requestsOne connection stays open
Bidirectional communicationClient and server can both send messages
EfficientAvoids repeated HTTP request overhead
Low latencyUseful for fast live updates

Real-World Challenges

WebSockets are powerful, but production systems need extra handling.

Common challenges:

  • sticky sessions
  • horizontal scaling
  • multi-server synchronization
  • connection limits
  • reconnection handling
  • message ordering
  • message reliability
  • security concerns
  • authentication handling
  • firewall and proxy issues
  • fallback support
  • testing and debugging complexity
  • resource cleanup
  • disconnect handling
  • memory leaks
WebSocket is simple to start, but real-world scaling needs careful design.

Short Polling vs Long Polling vs WebSockets

FeatureShort PollingLong PollingWebSocket
ConnectionRepeated requestsRequest waits, then reconnectsPersistent connection
DirectionClient asks serverClient asks serverClient and server both send
Real-timeNoAlmostYes
EfficiencyLowMediumHigh
Best ForSimple periodic checksBasic real-time updatesReal-time interactive apps

Frontend Code

This example builds a simple chat UI using Socket.IO.

<!DOCTYPE html>
<html>
<head>
<title>Simple Chat</title>

<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}

#messages {
list-style: none;
padding: 0;
max-width: 500px;
}

#messages li {
padding: 8px;
border-bottom: 1px solid #ddd;
}

form {
margin-top: 10px;
}

input {
padding: 8px;
width: 300px;
}

button {
padding: 8px 12px;
}
</style>
</head>

<body>
<h2>💬 Simple Chat</h2>

<ul id="messages"></ul>

<form id="form">
<input id="input" placeholder="Type message..." autocomplete="off" />

<button type="submit">Send</button>
</form>

<script src="/socket.io/socket.io.js"></script>

<script>
const socket = io();

const form = document.getElementById("form");
const input = document.getElementById("input");
const messages = document.getElementById("messages");

form.addEventListener("submit", (e) => {
e.preventDefault();

const msg = input.value.trim();

if (!msg) return;

socket.emit("chat-message", msg);

input.value = "";
});

socket.on("chat-message", (msg) => {
const li = document.createElement("li");

li.textContent = msg;
messages.appendChild(li);

window.scrollTo(0, document.body.scrollHeight);
});
</script>
</body>
</html>

Backend Code

This example uses Express, Node HTTP server, and Socket.IO.

const express = require("express");
const { createServer } = require("node:http");
const { join } = require("node:path");
const { Server } = require("socket.io");

const app = express();
const server = createServer(app);
const io = new Server(server);

// Serve frontend
app.get("/", (req, res) => {
res.sendFile(join(__dirname, "index.html"));
});

// Socket connection
io.on("connection", (socket) => {
console.log("User connected");

socket.on("chat-message", (msg) => {
console.log("Message:", msg);

io.emit("chat-message", msg);
});

socket.on("disconnect", () => {
console.log("User disconnected");
});
});

// Start server
server.listen(5000, () => {
console.log("Server running on http://localhost:5000");
});

What Happens in the Code

The frontend creates a WebSocket connection using Socket.IO.

const socket = io();

When the user submits the form, the client sends a message to the server.

socket.emit("chat-message", msg);

The backend receives that message.

socket.on("chat-message", (msg) => {
io.emit("chat-message", msg);
});

Then the server broadcasts the message to all connected clients.

io.emit("chat-message", msg);

Each client listens for the message and updates the UI.

socket.on("chat-message", (msg) => {
const li = document.createElement("li");
li.textContent = msg;
messages.appendChild(li);
});

How to Test

Install dependencies.

npm install express socket.io

Run the server.

node index.js

Open the app in multiple browser tabs.

http://localhost:5000

Send a message from one tab.

The message should appear in all connected tabs immediately.


WebSocket Table

AreaExplanation
Connection typePersistent connection
Communication directionFull-duplex, two-way
Protocol startStarts as HTTP, then upgrades
Server pushSupported
Client messagesSupported
Repeated requestsNot needed
Best fitReal-time interactive apps

Basic Checklist

Create HTTP server
Attach Socket.IO server
Listen for connection event
Emit events from client
Listen for events on server
Broadcast messages when needed
Handle disconnect event
Plan authentication for real apps
Handle reconnection
Clean resources when users disconnect
Plan scaling if multiple servers are used

Interview Style Answer

WebSocket is a communication technique that creates a persistent, full-duplex connection between the client and server. It starts as a normal HTTP request and then upgrades to a WebSocket connection using the Upgrade: websocket header. After the connection is opened, both client and server can send messages anytime without repeated HTTP requests. This makes WebSocket efficient and low-latency for real-time applications like chat apps, live trading, multiplayer games, and notifications. Compared to short polling and long polling, WebSocket is more suitable for continuous bidirectional communication, but real-world systems must handle scaling, reconnection, authentication, security, cleanup, and debugging carefully.


One-Line Summary

WebSocket = A persistent two-way connection that lets client and server send real-time messages anytime.

Final Mental Model

Short Polling -> repeated requests
Long Polling -> wait then reconnect
WebSocket -> connect once and talk anytime

Best for real-time two-way communication.