070
LVL 03 — MID DEVELOPERSESSION 070DAY 70

WEBSOCKETS & REAL-TIME

🎫 PIXELCRAFT-057
Feature | 🔴 Expert | Priority: 🟠 High

The PM's marquee feature: two users editing the same image simultaneously, seeing each other's changes in real-time. Like Google Docs for images.
CONCEPTS.UNLOCKED
🔄
HTTP Limitations
Client asks, server answers — server can't push updates. Request-response is half-duplex: one direction at a time. No way for the server to say "hey, something changed!" without being asked first.
🔌
WebSockets
Persistent bidirectional connection. Both sides can send data at any time over a single long-lived connection. Full-duplex — the foundation of real-time web applications.
📡
Socket.io
Library for real-time communication. Wraps WebSockets with fallbacks, auto-reconnection, and event-based API. The most popular real-time library for Node.js.
🚪
Rooms
Grouping connections by context. All editors of the same image join one room. Messages broadcast to the room reach only relevant users — not everyone connected.
Event-Driven Architecture
Emit events, listen for events. socket.emit('filter-change') → socket.on('filter-change'). Decoupled, reactive communication between clients and server.
💥
Conflict Handling
What if two users change the same thing? Simple: last-write-wins. Complex: Operational Transforms (Google Docs) or CRDTs (Figma). You'll start with last-write-wins.
HANDS-ON.TASKS
01
Install Socket.io
npm install socket.io # server npm install socket.io-client # client
02
Server-Side WebSocket Setup
const { Server } = require('socket.io'); const io = new Server(httpServer, { cors: { origin: '*' } }); io.on('connection', (socket) => { console.log('User connected:', socket.id); // Join an image editing room socket.on('join-image', (imageId) => { socket.join(`image:${imageId}`); const users = io.sockets.adapter .rooms.get(`image:${imageId}`); io.to(`image:${imageId}`) .emit('users-updated', { count: users?.size || 0 }); }); // Broadcast filter changes to other editors socket.on('filter-change', ({ imageId, filterName, value }) => { socket.to(`image:${imageId}`) .emit('filter-change', { filterName, value, userId: socket.id }); }); // Broadcast cursor position socket.on('cursor-move', ({ imageId, x, y }) => { socket.to(`image:${imageId}`) .emit('cursor-move', { x, y, userId: socket.id }); }); socket.on('disconnect', () => { console.log('User disconnected:', socket.id); }); });
03
Client-Side Collaboration Hook
function useCollaboration(imageId) { const [socket, setSocket] = useState(null); const [collaborators, setCollaborators] = useState([]); useEffect(() => { const s = io(API_URL); setSocket(s); s.emit('join-image', imageId); s.on('filter-change', ({ filterName, value, userId }) => { // Apply the remote user's filter change dispatch({ type: 'SET_FILTER', payload: { name: filterName, value } }); }); s.on('cursor-move', ({ x, y, userId }) => { setCollaborators(prev => ({ ...prev, [userId]: { x, y, lastSeen: Date.now() }, })); }); s.on('users-updated', ({ count }) => { // Show "2 people editing" }); return () => s.disconnect(); }, [imageId]); const emitFilterChange = (filterName, value) => { socket?.emit('filter-change', { imageId, filterName, value }); }; const emitCursorMove = (x, y) => { socket?.emit('cursor-move', { imageId, x, y }); }; return { collaborators, emitFilterChange, emitCursorMove }; }
04
Test Real-Time Collaboration

Open two browser windows, same image. Move a slider in one → the other updates instantly. Show collaborator cursors on the canvas with colored indicators.

05
Close the Ticket
git switch -c feature/PIXELCRAFT-057-realtime-collab git add server/ src/ git commit -m "Add WebSocket real-time collaboration (PIXELCRAFT-057)" git push origin feature/PIXELCRAFT-057-realtime-collab # PR → Review → Merge → Close ticket ✅
CS.DEEP-DIVE

The client-server model has evolved.

HTTP is request-response (half-duplex). WebSockets are full-duplex — both sides send at any time over a persistent connection.

// HTTP vs WebSockets:

HTTP (half-duplex)
  Client → Server → Client
  New connection every request
  Server can't push to client

WebSocket (full-duplex)
  Client ↔ Server (both ways)
  Single persistent connection
  Server can push anytime

// This enables:
// Chat (Slack, Discord)
// Multiplayer games
// Live dashboards, stock tickers
// Collaborative editing (Figma, Docs)

// Conflict resolution strategies:
Last-write-wins → simple (you're here)
OT → Operational Transforms (Google Docs)
CRDTs → Conflict-free Replicated Data Types
"Collab Lab"
[A]Add presence indicators: show colored avatars of active editors on the canvas. When a user leaves, fade out their cursor after 3 seconds. Show "2 people editing" badge.
[B]Add a real-time chat sidebar: users editing the same image can send messages. Use Socket.io rooms to scope chat per image. Store last 50 messages in Redis.
[C]Research CRDTs (Conflict-free Replicated Data Types). How does Figma handle simultaneous edits? Compare OT vs CRDT tradeoffs. Write a brief analysis document.
REF.MATERIAL
ARTICLE
Socket.io Team
Official Socket.io guide: events, rooms, namespaces, middleware, and scaling. The definitive real-time library reference.
SOCKET.IOOFFICIALESSENTIAL
VIDEO
Fireship
Ultra-fast WebSocket overview: the upgrade handshake, persistent connections, and real-time use cases explained visually.
WEBSOCKETSQUICK
ARTICLE
MDN Web Docs
The raw WebSocket API: creating connections, sending messages, handling events. Understanding what Socket.io abstracts.
WEBSOCKETSMDNOFFICIAL
ARTICLE
Evan Wallace, Figma
Inside Figma's real-time engine: CRDTs, conflict resolution, and the architecture powering collaborative design at scale.
CRDTARCHITECTURE
VIDEO
Traversy Media
Practical Socket.io tutorial: rooms, events, broadcasting, and building a full chat application from scratch.
SOCKET.IOTUTORIAL
// LEAVE EXCITED BECAUSE
Two browser windows editing the same image. Move a slider in one → the other updates instantly. See the other user's cursor moving on the canvas. This is the magic of apps like Figma and Google Docs — and you built it.