JavaScript WebSockets
A WebSocket is a communication channel that stays open between your browser and a server. Unlike a normal HTTP request — which is one-way and closes after the server replies — a WebSocket keeps the connection alive so both sides can send messages to each other at any time. This makes it the right tool for real-time features like chat apps, live scores, stock prices, and multiplayer games.
HTTP Request vs WebSocket
Diagram: The Key Difference
Normal HTTP (one request, one response): Browser ──── GET /data ────► Server Browser ◄─── response ────── Server [connection closed] Browser ──── GET /data ────► Server (request again for updates) Browser ◄─── response ────── Server [repeat every few seconds — inefficient] WebSocket (persistent two-way channel): Browser ◄────── handshake ──────► Server [connection stays open] Browser ──── message ──────────► Server Browser ◄─── message ────────── Server Browser ◄─── message ────────── Server (server pushes anytime) Browser ──── message ──────────► Server [connection stays open until closed]
Creating a WebSocket Connection
Pass the server's WebSocket URL to the WebSocket constructor. WebSocket URLs use ws:// (or wss:// for secure connections — always prefer this in production).
let socket = new WebSocket("wss://echo.websocket.org");
WebSocket Events
WebSocket communication is entirely event-driven. You respond to four events: open, message, close, and error.
onopen — Connection Established
socket.onopen = function(event) {
console.log("Connected to server!");
socket.send("Hello, Server!"); // send a message right away
};
onmessage — Message Received from Server
socket.onmessage = function(event) {
console.log("Message from server:", event.data);
};
onclose — Connection Closed
socket.onclose = function(event) {
console.log("Connection closed. Code:", event.code);
};
onerror — Error Occurred
socket.onerror = function(error) {
console.log("WebSocket error:", error);
};
Sending Messages
Use socket.send() to send a string, JSON, or binary data to the server.
// Send a plain string
socket.send("Hello!");
// Send structured data as JSON
let message = {
type: "chat",
user: "Priya",
text: "Hey, is anyone online?"
};
socket.send(JSON.stringify(message));
Receiving and Parsing Messages
socket.onmessage = function(event) {
let data = JSON.parse(event.data);
if (data.type === "chat") {
console.log(data.user + ": " + data.text);
} else if (data.type === "notification") {
console.log("Notification:", data.text);
}
};
Diagram: Message Round-Trip
Browser Server │ │ │── send(JSON.stringify(message)) ───►│ │ │ (server processes) │◄── onmessage(event) ───────────────│ │ event.data = JSON string │ │ JSON.parse(event.data) → object │
Closing a Connection
// Close from the browser side
socket.close();
// Close with a code and reason
socket.close(1000, "User logged out");
WebSocket readyState
The readyState property tells you the current state of the connection.
| Value | Constant | Meaning |
|---|---|---|
| 0 | CONNECTING | Connection not yet open |
| 1 | OPEN | Connection is open and ready |
| 2 | CLOSING | Connection is being closed |
| 3 | CLOSED | Connection is closed |
if (socket.readyState === WebSocket.OPEN) {
socket.send("Safe to send!");
} else {
console.log("Socket not ready. State:", socket.readyState);
}
Real-World Example: Simple Chat App
let socket = new WebSocket("wss://your-chat-server.com");
let messages = [];
socket.onopen = function() {
console.log("Chat connected!");
};
socket.onmessage = function(event) {
let msg = JSON.parse(event.data);
messages.push(msg);
displayMessage(msg);
};
socket.onclose = function() {
console.log("Disconnected from chat.");
};
socket.onerror = function() {
console.log("Connection error. Please try again.");
};
function sendMessage(user, text) {
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({ user, text }));
}
}
function displayMessage(msg) {
console.log(msg.user + ": " + msg.text);
}
// Send a message
sendMessage("Rahul", "Hello everyone!");
Diagram: Chat App Flow
User A types "Hello"
│
socket.send({ user: "A", text: "Hello" })
│
──────────────────────────────► Server
│
broadcasts to all ◄──┘
connected clients
│
User A ◄──────────┤
User B ◄──────────┤
User C ◄──────────┘
all see: "A: Hello"
Auto-Reconnect Pattern
WebSocket connections can drop due to network issues. Build a reconnect loop to restore them automatically.
function connectWebSocket() {
let socket = new WebSocket("wss://your-server.com");
socket.onopen = () => console.log("Connected");
socket.onmessage = (event) => {
console.log("Received:", event.data);
};
socket.onclose = () => {
console.log("Disconnected. Reconnecting in 3 seconds...");
setTimeout(connectWebSocket, 3000); // try again after 3 seconds
};
socket.onerror = () => {
socket.close(); // triggers onclose which retries
};
}
connectWebSocket();
Diagram: Reconnect Loop
Connect → Open → Messages flow
│
Connection drops
│
onclose fires
│
setTimeout 3 seconds
│
Connect again → Open → Messages flow
WebSocket vs Other Real-Time Approaches
| Method | Direction | Connection | Best For |
|---|---|---|---|
| HTTP Polling | One-way | Opens & closes | Simple infrequent updates |
| Server-Sent Events | Server → Browser only | Persistent | News feeds, notifications |
| WebSocket | Both ways | Persistent | Chat, games, live collaboration |
Summary
WebSockets create a persistent, two-way connection between browser and server. They replace repeated HTTP polling for real-time features. Four events drive the API: onopen, onmessage, onclose, and onerror. Use socket.send() to push messages and socket.close() to end the session. Always use wss:// in production for encrypted connections, and build a reconnect handler to recover from dropped connections automatically.
