Dung (Donny) Nguyen

Senior Software Engineer

Server-side Room Join/Leave Patterns

Here is a clear and modern example of how to handle server-side room join/leave patterns in a Socket.IO application, based on common real-world use cases such as chat or game lobbies.[1][2][3][5]

Server-side Implementation

const { Server } = require('socket.io');
const io = new Server(3000, {
  cors: { origin: "*" }
});

function logClientsInRoom(roomName) {
  const clients = Array.from(io.sockets.adapter.rooms.get(roomName) || []);
  console.log(`Clients in ${roomName}:`, clients);
}

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

  // Join a room
  socket.on('joinRoom', data => {
    const { roomName, userName } = data;
    socket.join(roomName); // Add the socket to that room
    console.log(`${userName} joined ${roomName}`);
    io.to(roomName).emit('userJoined', { userName, id: socket.id });
    logClientsInRoom(roomName);
    socket.emit('roomJoined', { roomName });
  });

  // Leave a room
  socket.on('leaveRoom', data => {
    const { roomName, userName } = data;
    socket.leave(roomName); // Removes socket from the room
    console.log(`${userName} left ${roomName}`);
    io.to(roomName).emit('userLeft', { userName, id: socket.id });
    logClientsInRoom(roomName);
    socket.emit('roomLeft', { roomName });
  });

  // Send message within a room
  socket.on('message', ({ roomName, text }) => {
    io.to(roomName).emit('message', { text, sender: socket.id });
  });

  // Handle disconnect events safely
  socket.on('disconnecting', () => {
    // Access rooms the socket is still part of before disconnect
    for (const room of socket.rooms) {
      if (room !== socket.id) {
        io.to(room).emit('userLeft', { id: socket.id });
      }
    }
  });
});

Client-side Example

const socket = io('http://localhost:3000');

// Join a room
socket.emit('joinRoom', { roomName: 'room1', userName: 'Alice' });

// Listen for updates
socket.on('userJoined', data => console.log(`${data.userName} joined!`));
socket.on('userLeft', data => console.log(`${data.userName} left!`));

// Leave room
socket.emit('leaveRoom', { roomName: 'room1', userName: 'Alice' });

Key Patterns

This pattern efficiently scales from chat systems to real-time multiplayer games requiring grouped communication channels.

1 2 3 4 5 6 7 8