title: Socket.io: How to correctly join and leave rooms
body: <p>I'm trying to learn Socket.io by building a set of dynamically created chatrooms that emit 'connected' and 'disconnected' messages when users enter and leave. After looking at a <a href="https://stackoverflow.com/questions/15909821/socket-io-join-leave">couple</a> <a href="https://stackoverflow.com/questions/19150220/creating-rooms-in-socket-io">of</a> <a href="https://stackoverflow.com/questions/34093173/how-to-get-current-room-of-socket-on-disconnect">questions</a> I've put together something functional but most of the response linked are from people who admit they've hacked together answers and I've noticed there's a more general - and recent - discussion about the right way to do this on the Socket.io repo (notably <a href="https://github.com/socketio/socket.io/issues/2266" rel="noreferrer">here</a> and <a href="https://github.com/socketio/socket.io/issues/1814" rel="noreferrer">here</a>)</p>
  
  <p>As I'm such a novice I don't know if the work below is an acceptable way to do things or it just happens to incidentally function but will cause performance issues or result in too many listeners. If there's an ideal - and official - way to join and leave rooms that feels less clunky than this I'd love to learn about it.</p>
  
  <p><strong>Client</strong></p>
  
  <pre><code>var roomId = ChatRoomData._id // comes from a factory
  
  
  function init() {
  
      // Make sure the Socket is connected
      if (!Socket.socket) {
          Socket.connect();
      }
  
      // Sends roomId to server
      Socket.on('connect', function() {
          Socket.emit('room', roomId);
      });
  
      // Remove the event listener when the controller instance is destroyed
      $scope.$on('$destroy', function () {
          Socket.removeListener('connect');
      });
  
  }
  
  init();
  </code></pre>
  
  <p><strong>Server</strong></p>
  
  <pre><code>  io.sockets.once('connection', function(socket){
      socket.on('room', function(room){     // take room variable from client side
        socket.join(room) // and join it
  
        io.sockets.in(room).emit('message', {      // Emits a status message to the connect room when a socket client is connected
          type: 'status',
          text: 'Is now connected',
          created: Date.now(),
          username: socket.request.user.username
        });
  
        socket.on('disconnect', function () {   // Emits a status message to the connected room when a socket client is disconnected
          io.sockets.in(room).emit({ 
            type: 'status',
            text: 'disconnected',
            created: Date.now(),
            username: socket.request.user.username
          });  
        })
    });
  </code></pre>