Day 2 of 5
⏱ ~60 minutes
WebSockets in 5 Days — Day 2

Socket.io Basics

Server setup, emitting events, client connections, namespaces.

Why Socket.io Instead of Raw WebSockets?

Raw WebSockets are powerful but minimal — you get a message channel and that's it. Socket.io adds rooms, namespaces, automatic reconnection, event names, and fallback to HTTP long-polling when WebSockets aren't available. For most real-time apps, Socket.io is the right choice.

💡
Socket.io vs raw WebSockets: Use raw ws when you need the lowest latency and smallest payload (gaming, IoT). Use Socket.io for app-level features: chat, notifications, live updates.

Setting Up a Socket.io Server

server.js — Socket.io Setup
const express = require('express');
const { createServer } = require('http');
const { Server } = require('socket.io');

const app = express();
const httpServer = createServer(app);
const io = new Server(httpServer, {
  cors: { origin: '*' } // Configure properly in production
});

io.on('connection', (socket) => {
  console.log('User connected:', socket.id);

  // Listen for a 'message' event from the client
  socket.on('message', (data) => {
    console.log('Message from', socket.id, ':', data);
    // Emit back to everyone including sender
    io.emit('message', { from: socket.id, text: data });
  });

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

httpServer.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

Emitting Events

Socket.io uses named events rather than raw messages. This makes your code much easier to read and maintain. There are four main ways to emit:

Emit Patterns
// To the sender only
socket.emit('event', data);

// To everyone except the sender
socket.broadcast.emit('event', data);

// To everyone including sender
io.emit('event', data);

// To a specific room
io.to('room-name').emit('event', data);

Namespaces

Namespaces let you create separate communication channels on the same server. Each namespace has its own event handlers and rooms — useful for separating admin traffic from user traffic or building multi-tenant apps.

Namespaces
// Server: create a namespace
const adminNS = io.of('/admin');
adminNS.on('connection', (socket) => {
  socket.emit('welcome', 'You are in the admin namespace');
});

// Client: connect to a namespace
const adminSocket = io('/admin');
adminSocket.on('welcome', (msg) => console.log(msg));
📝 Day 2 Exercise
Socket.io Counter App
  1. Install: npm install express socket.io
  2. Build a server that tracks a counter. When any client emits increment, the server increments and broadcasts the new count.
  3. Create a simple HTML page with two buttons: Increment and Decrement. Connect via Socket.io CDN.
  4. Open multiple browser tabs and verify all tabs update in real time.
  5. Add a reset event that only admin clients (use a query param to identify) can send.

Day 2 Summary

  • Socket.io adds rooms, namespaces, auto-reconnect, and named events on top of WebSockets.
  • Named events (socket.on('eventName')) make code readable and maintainable.
  • Four emit patterns: to sender, to others, to all, to a room.
  • Namespaces isolate traffic without multiple servers.
Finished this lesson?