WebSockets (ws & Socket.IO)

WebSockets keep a single connection open so the server and client can push messages to each other at any time, making them the foundation for real-time features like chat, live dashboards, and multiplayer games.

Learn WebSockets (ws & Socket.IO) in our free Node.js course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…

Part of the free Node.js course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll see how WebSockets differ from request/response HTTP, write a server with the lean ws library, use Socket.IO's events, rooms, and broadcasting, and learn when a WebSocket is the right tool versus plain HTTP.

What You'll Learn in This Lesson

1️⃣ HTTP vs WebSocket: the emit/on Model

With HTTP, the client asks and the server answers, then the exchange is over. With a WebSocket, the connection stays open and both sides communicate by emitting named events and listening for them — exactly the pattern of Node's EventEmitter , which is why we use it to model the idea.

In the snippet below, socket.on('name', handler) subscribes to an event and socket.emit('name', data) fires one. The server reacts to a client message and pushes one back — the two-way flow that defines WebSockets.

2️⃣ A Real Server with the ws Library

The ws library is the lean, standards-based choice. You create a WebSocketServer , handle the 'connection' event for each client, then listen for that client's 'message' and call socket.send(...) to push data back. The browser's built-in WebSocket object talks to it directly — no client library needed.

3️⃣ Socket.IO: Events, Rooms & Broadcasting

Socket.IO layers convenience on top of WebSockets: named events, automatic reconnection, and rooms . A room is a named group of connections. A socket join() s a room, and you broadcast with io.to(room).emit(...) (everyone in it) or socket.to(room).emit(...) (everyone except the sender).

Here's the rooms-and-broadcast logic as a runnable plain-Node model, so you can see exactly who receives a broadcast and who doesn't:

Your turn. The ping/pong below works once you fill in the single blank marked ___ . Follow the 👉 hint, then run it.

Mini-Challenge: A Two-Client Chat

No blanks — just a brief and an outline. Model a two-person chat over one shared event bus, where each client sees the other's messages but not its own. Write it, run it, and compare with the example output.

Common Errors (and the fix)

Pro Tips

📋 Quick Reference — WebSocket Messaging

Task

Syntax

Listen for an event

socket.on('name', fn)

Send an event

socket.emit('name', data)

ws: send to a client

socket.send(text)

Join a room

socket.join(room)

To everyone in a room

io.to(room).emit(...)

To room, not sender

socket.to(room).emit(...)

Secure connection

wss://host

Frequently Asked Questions

🎉 Lesson Complete!

Practice quiz

What is the key difference between HTTP and WebSockets?

  • WebSockets keep one connection open so either side can push anytime
  • HTTP is always faster
  • WebSockets cannot send text
  • HTTP keeps a persistent socket

Answer: WebSockets keep one connection open so either side can push anytime. A WebSocket is a persistent full-duplex channel; HTTP is request/response.

Which Node built-in models the emit/on event style used by Socket.IO?

  • fs
  • EventEmitter
  • Buffer
  • cluster

Answer: EventEmitter. EventEmitter's on()/emit() pattern mirrors how WebSocket messaging works.

With the ws library, in what form do incoming messages arrive?

  • A parsed JSON object
  • A number
  • A Buffer (call .toString() for text)
  • An HTML string

Answer: A Buffer (call .toString() for text). ws delivers messages as Buffers; use data.toString() to read text.

How does a socket join a named group in Socket.IO?

  • socket.group(name)
  • io.add(name)
  • socket.room = name
  • socket.join(room)

Answer: socket.join(room). socket.join('room') adds the connection to that room.

Which call broadcasts to everyone in a room EXCEPT the sender?

  • socket.to(room).emit(...)
  • io.to(room).emit(...)
  • io.emit(...)
  • socket.send(...)

Answer: socket.to(room).emit(...). socket.to(room) excludes the sender; io.to(room) includes everyone.

Why can't a browser's native WebSocket connect to a Socket.IO server?

  • The port is blocked
  • Socket.IO uses its own protocol, needing socket.io-client
  • Native WebSocket is deprecated
  • Socket.IO only accepts HTTP

Answer: Socket.IO uses its own protocol, needing socket.io-client. Socket.IO has its own protocol; the browser must use socket.io-client.

When is a simpler alternative than WebSockets a better fit?

  • For multiplayer games
  • For high-frequency two-way updates
  • For occasional one-way server pushes (Server-Sent Events)
  • Never, WebSockets always win

Answer: For occasional one-way server pushes (Server-Sent Events). SSE is simpler when only the server needs to push occasionally.

Which library is the lean, standards-based WebSocket choice?

  • socket.io
  • express
  • axios
  • ws

Answer: ws. ws speaks the raw WebSocket protocol the browser's WebSocket understands.

On an HTTPS page, which WebSocket scheme must you use?

  • wss://
  • ws://
  • http://
  • ftp://

Answer: wss://. Browsers block insecure ws:// on secure pages; use wss:// over TLS.

What problem appears when running Socket.IO across multiple instances?

  • Messages are encrypted twice
  • Each instance only knows its own connections, so rooms break
  • The port changes randomly
  • Clients can't reconnect at all

Answer: Each instance only knows its own connections, so rooms break. You need the Redis adapter or sticky sessions so rooms span all instances.

Continue this course