Day 03 Applied Skills

Building a Chat App

Rooms, private messages, user presence, message history. Part of the free WebSockets in 5 Days course at Precision AI Academy.

~1 hour Hands-on Precision AI Academy

Today's Objective

Rooms, private messages, user presence, message history. Part of the free WebSockets in 5 Days course at Precision AI Academy.

01

Chat App Architecture

A real chat app needs: rooms (channels), user presence (who's online), private messages, and message history. We'll build all four today. The server is the single source of truth — it manages room membership and broadcasts messages.

02

Rooms

Rooms — Join and Leave
Rooms — Join and Leave
io.on('connection', (socket) => {
  // Join a room
  socket.on('joinRoom', (room) => {
    socket.join(room);
    // Tell others in the room
    socket.to(room).emit('userJoined', { 
      userId: socket.id, room 
    });
    socket.emit('joinedRoom', room);
  });

  // Send to a room
  socket.on('roomMessage', ({ room, message }) => {
    io.to(room).emit('newMessage', {
      from: socket.id,
      message,
      time: new Date().toISOString()
    });
  });

  // Leave a room
  socket.on('leaveRoom', (room) => {
    socket.leave(room);
    socket.to(room).emit('userLeft', socket.id);
  });
});
03

User Presence

Track who's online using a simple in-memory Map. In production you'd use Redis, but for a single-server app a Map works fine.

Presence Tracking
Presence Tracking
const onlineUsers = new Map(); // socketId -> username

io.on('connection', (socket) => {
  socket.on('setUsername', (username) => {
    onlineUsers.set(socket.id, username);
    io.emit('onlineUsers', Array.from(onlineUsers.values()));
  });

  socket.on('disconnect', () => {
    const username = onlineUsers.get(socket.id);
    onlineUsers.delete(socket.id);
    io.emit('userLeft', username);
    io.emit('onlineUsers', Array.from(onlineUsers.values()));
  });
});
04

Private Messages

Private Messages
Private Messages
socket.on('privateMessage', ({ to, message }) => {
  // Each socket automatically joins a room named by its own ID
  io.to(to).emit('privateMessage', {
    from: socket.id,
    message,
    time: new Date().toISOString()
  });
  // Also emit to sender so they see their own message
  socket.emit('privateMessage', {
    from: socket.id, to, message,
    time: new Date().toISOString()
  });
});

Supporting References & Reading

Go deeper with these external resources.

Docs
Building a Chat App Official documentation for websockets.
GitHub
Building a Chat App Open source examples and projects for Building a Chat App
MDN
MDN Web Docs Comprehensive web technology reference

Day 3 Checkpoint

Before moving on, confirm understanding of these key concepts:

Continue To Day 4
Day 4 of the WebSockets in 5 Days course