Socket.io: How to correctly join and leave rooms
<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>