Unit 6.2 · Tutorial 1

WebSockets & Socket.io

Chapter 18 · Advanced Topics
~2.5 hours Intermediate WebSockets · Socket.io · Realtime · Rooms

Overview

WebSockets enable full‑duplex, real‑time communication between client and server. This tutorial covers the WebSocket protocol and Socket.io — the most popular real‑time library for Node.js. You'll learn to emit and listen to events, use rooms and namespaces, and broadcast messages.

Why this matters: Real‑time features (chat, notifications, live updates, collaborative tools) are essential for modern applications. WebSockets make these possible with low latency and high efficiency.

1. WebSocket Protocol

WebSocket is a protocol that provides a persistent, bidirectional communication channel over a single TCP connection.

  • HTTP upgrade: Starts with an HTTP request, then upgrades to WebSocket.
  • Full‑duplex: Both client and server can send messages at any time.
  • Low latency: No HTTP headers overhead after connection.
  • Use cases: Chat, gaming, live sports, financial tickers, collaborative editing.
// WebSocket client (browser API) const ws = new WebSocket('ws://localhost:8080'); ws.onopen = () => { console.log('Connected to WebSocket server'); ws.send('Hello, server!'); }; ws.onmessage = (event) => { console.log('Message from server:', event.data); }; ws.onclose = () => { console.log('Disconnected from server'); };
// WebSocket server (ws library) import { WebSocketServer } from 'ws'; const wss = new WebSocketServer({ port: 8080 }); wss.on('connection', (ws) => { ws.on('message', (data) => { console.log('Received:', data.toString()); ws.send(`Echo: ${data}`); }); ws.send('Welcome to the WebSocket server!'); });
Note: While the native WebSocket API works, Socket.io provides additional features like automatic reconnection, rooms, and fallback transports.

2. Socket.io Basics

Socket.io is a library that enables real‑time, bidirectional communication with features beyond the WebSocket protocol.

# Install Socket.io npm install socket.io npm install socket.io-client
// Server (Node.js + Express) import express from 'express'; import http from 'http'; import { Server } from 'socket.io'; const app = express(); const server = http.createServer(app); const io = new Server(server, { cors: { origin: '*' } }); io.on('connection', (socket) => { console.log('New client connected:', socket.id); socket.on('disconnect', () => { console.log('Client disconnected:', socket.id); }); }); server.listen(3000, () => { console.log('Server running on port 3000'); });
// Client (React) import { useEffect, useState } from 'react'; import io from 'socket.io-client'; const socket = io('http://localhost:3000'); function ChatApp() { const [connected, setConnected] = useState(false); useEffect(() => { socket.on('connect', () => setConnected(true)); socket.on('disconnect', () => setConnected(false)); return () => socket.disconnect(); }, []); return
Status: {connected ? 'Connected' : 'Disconnected'}
; }

3. Emitting & Listening to Events

Socket.io uses events for communication. Use emit() to send events and on() to listen.

// Server io.on('connection', (socket) => { // Listen for 'message' event socket.on('message', (data) => { console.log('Received:', data); // Emit 'response' event back to client socket.emit('response', { echo: data }); }); // Emit 'welcome' event on connection socket.emit('welcome', { message: 'Welcome!' }); });
// Client socket.emit('message', { text: 'Hello, server!' }); socket.on('response', (data) => { console.log('Server responded:', data); }); socket.on('welcome', (data) => { console.log('Welcome message:', data.message); });

Event naming: Use meaningful names (e.g., 'chat:message', 'user:joined', 'notification:new').

4. Rooms & Namespaces

Rooms

Rooms allow you to send messages to a subset of connected clients.

// Server – join a room socket.on('joinRoom', (roomId) => { socket.join(roomId); socket.to(roomId).emit('userJoined', { userId: socket.id, roomId }); }); // Send message to a room socket.on('roomMessage', ({ roomId, message }) => { io.to(roomId).emit('roomMessage', { userId: socket.id, message, timestamp: new Date() }); }); // Leave a room socket.on('leaveRoom', (roomId) => { socket.leave(roomId); });

Namespaces

Namespaces separate communication channels (e.g., /chat, /notifications).

// Server – define a namespace const chatNamespace = io.of('/chat'); chatNamespace.on('connection', (socket) => { // Handles only connections to /chat }); // Client – connect to a namespace const chatSocket = io('/chat');

5. Broadcasting

Broadcasting sends a message to all clients except the sender.

// Server – broadcast to all except sender socket.broadcast.emit('userTyping', { userId: socket.id }); // Broadcast to all clients in a room (except sender) socket.broadcast.to('room-123').emit('message', data); // Broadcast to all clients globally (including sender) io.emit('systemNotification', { message: 'Maintenance in 5 minutes' }); // Broadcast to all clients in a namespace (except sender) chatNamespace.to(roomId).emit('newMessage', data);
// Example: typing indicator socket.on('typing', ({ roomId, isTyping }) => { socket.to(roomId).emit('userTyping', { userId: socket.id, isTyping }); });

Quiz

Question 1

What protocol does WebSocket use for the initial handshake?

  • FTP
  • HTTP
  • SMTP
  • TCP
Show answer
B. HTTP (with an upgrade header).

Question 2

What is the difference between io.emit() and socket.broadcast.emit()?

  • io.emit sends to all clients; broadcast.emit sends to all except the sender
  • io.emit sends to the sender only; broadcast.emit sends to all
  • There is no difference
  • io.emit is deprecated
Show answer
A. io.emit sends to all clients; broadcast.emit sends to all except the sender.

Question 3

What is the purpose of rooms in Socket.io?

  • To store chat history
  • To group clients for targeted messaging
  • To encrypt messages
  • To load balance connections
Show answer
B. To group clients for targeted messaging.

Exercises

Exercise 1

Create a Socket.io server that broadcasts a 'ping' event to all connected clients every 5 seconds.

Sample answer
io.on('connection', (socket) => { console.log('Client connected'); // Broadcast ping every 5 seconds const interval = setInterval(() => { io.emit('ping', { timestamp: Date.now() }); }, 5000); socket.on('disconnect', () => { clearInterval(interval); console.log('Client disconnected'); }); });

Exercise 2

Write a React component that connects to a Socket.io server, listens for a 'notification' event, and displays the notifications in a list.

Sample answer
import { useEffect, useState } from 'react'; import io from 'socket.io-client'; function Notifications() { const [notifications, setNotifications] = useState([]); const [socket, setSocket] = useState(null); useEffect(() => { const newSocket = io('http://localhost:3000'); setSocket(newSocket); newSocket.on('notification', (data) => { setNotifications(prev => [...prev, data.message]); }); return () => newSocket.disconnect(); }, []); return (
    {notifications.map((msg, i) => (
  • {msg}
  • ))}
); }

Homework

Homework 1

Implement a simple chat application using Socket.io with: (1) Multiple rooms, (2) User join/leave notifications, (3) Typing indicators, (4) Message history (last 50 messages).

Sample outline
  • Server: Socket.io server with rooms, message storage (in‑memory).
  • Client: React chat UI with room selection, message list, and message input.
  • Features: Join room, leave room, typing indicator, message history.

Mini‑Project

Real‑Time Dashboard

Build a real‑time dashboard that displays live data:

  • Server emits 'update' events every second with random data (e.g., stock prices, sensor readings)
  • Client receives updates and renders charts (using Chart.js or Recharts)
  • Multiple clients can connect and receive the same data
  • Add a filter to show/hide specific data streams
Sample outline
  • Server: Socket.io server that emits random data points for 3 different sensors.
  • Client: React app with real‑time charts (Recharts) that update every second.
  • Controls: Toggle buttons to show/hide specific data streams.
  • History: Store last 30 data points per stream.

Tutorial Summary

You learned the fundamentals of real‑time communication using WebSockets and Socket.io. You covered event handling, rooms, namespaces, broadcasting, and built a foundation for real‑time applications. These skills are essential for modern, interactive applications.

Key takeaway: Socket.io makes real‑time communication accessible and reliable. Use rooms and namespaces to organise your application's real‑time features.