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:
| Code | Meaning |
|---|---|
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.
| Advantage | Meaning |
|---|---|
| Real-time communication | Data can be sent instantly |
| No repeated requests | One connection stays open |
| Bidirectional communication | Client and server can both send messages |
| Efficient | Avoids repeated HTTP request overhead |
| Low latency | Useful 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
| Feature | Short Polling | Long Polling | WebSocket |
|---|---|---|---|
| Connection | Repeated requests | Request waits, then reconnects | Persistent connection |
| Direction | Client asks server | Client asks server | Client and server both send |
| Real-time | No | Almost | Yes |
| Efficiency | Low | Medium | High |
| Best For | Simple periodic checks | Basic real-time updates | Real-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
| Area | Explanation |
|---|---|
| Connection type | Persistent connection |
| Communication direction | Full-duplex, two-way |
| Protocol start | Starts as HTTP, then upgrades |
| Server push | Supported |
| Client messages | Supported |
| Repeated requests | Not needed |
| Best fit | Real-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.