Socket.io:如何正确加入和离开房间

bro*_*kyo 7 sockets node.js socket.io

我正在尝试通过构建一组动态创建的聊天室来学习Socket.io,这些聊天室在用户进入和离开时会发出"已连接"和"已断开连接"的消息.看着后夫妇 问题,我已经把一些功能,但大多数链接的响应是从谁承认他们已经一起黑客攻击的人的答案和我注意到有一个更通用-关于正确的方式来讨论-和最近在Socket.io repo上做这个(特别是这里这里)

由于我是这样的新手,我不知道下面的工作是否是一种可接受的做事方式,或者只是偶然发生功能,但会导致性能问题或导致听众太多.如果有一种理想的 - 官方的 - 加入和离开房间的方式感觉不那么笨重,我很乐意了解它.

客户

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();
Run Code Online (Sandbox Code Playgroud)

服务器

  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
        });  
      })
  });
Run Code Online (Sandbox Code Playgroud)

EMX*_*EMX 8

Socket.IO:最近发布的v2.0.3

关于加入/离开房间 [阅读文档。]

加入一个房间一样简单socket.join('roomName'

//:JOIN:Client Supplied Room
socket.on('subscribe',function(room){  
  try{
    console.log('[socket]','join room :',room)
    socket.join(room);
    socket.to(room).emit('user joined', socket.id);
  }catch(e){
    console.log('[error]','join room :',e);
    socket.emit('error','couldnt perform requested action');
  }
})
Run Code Online (Sandbox Code Playgroud)

离开房间,就这么简单socket.leave('roomName');

//:LEAVE:Client Supplied Room
socket.on('unsubscribe',function(room){  
  try{
    console.log('[socket]','leave room :', room);
    socket.leave(room);
    socket.to(room).emit('user left', socket.id);
  }catch(e){
    console.log('[error]','leave room :', e);
    socket.emit('error','couldnt perform requested action');
  }
})
Run Code Online (Sandbox Code Playgroud)

通知房间房间用户正在断开连接

在断开连接事件时无法获取客户端当前所在的房间列表

已修复(添加“断开连接”事件以在断开连接时访问socket.rooms)

 socket.on('disconnect', function(){(
    /*
      socket.rooms is empty here 
      leaveAll() has already been called
    */
 });
 socket.on('disconnecting', function(){
   // socket.rooms should isn't empty here 
   var rooms = socket.rooms.slice();
   /*
     here you can iterate over the rooms and emit to each
     of those rooms where the disconnecting user was. 
   */
 });
Run Code Online (Sandbox Code Playgroud)

现在发送到特定房间:

// sending to all clients in 'roomName' room except sender
  socket.to('roomName').emit('event', 'content');
Run Code Online (Sandbox Code Playgroud)

Socket.IO发射备忘单