Socket.io 不会在断开连接时向房间发送消息

Posted

技术标签:

【中文标题】Socket.io 不会在断开连接时向房间发送消息【英文标题】:Socket.io Won't Emit messages to rooms on discconect 【发布时间】:2014-09-28 10:50:45 【问题描述】:

基本上我正在尝试使用 Node.JS 和 angular 创建一个快速聊天室。

我已经使用了其他套接字事件并且它们工作了我不太明白为什么他们现在不想工作。真正奇怪的是,登录工作正常而且非常好,但是当涉及到注销时,甚至使用我的断开连接方法时,服务器端没有任何反应,使用断开连接功能,console.log 工作正常。但它不会发射。

在角度方面,我的所有console.logs 都在运行,但在注销或断开连接时没有任何事件影响服务器。

在节点内部我有三个事件

 socket.on('chat:userLogin', function(user) 
    socket.join('online-users');
    chatRoom[user.id] = user
    console.log('User Has logged in, chat room contains: ', chatRoom);
    io.sockets.in('online-users').emit('chat:usersOnline', chatRoom)
  )

  socket.on('chat:userLogout', function(userId) 
    console.log('User Id ' + userId + 'is logging out');
    delete chatRoom[userId]
    console.log('User Has logged out, chat room contains: ', chatRoom);
    io.sockets.in('online-users').emit('chat:userLeave', chatRoom);
    socket.leave('online-users');
  )

  socket.on('disconnect', function() 
    var userRoom = rooms[socket.roomId]

    if (chatRoom[socket.userId])
      delete chatRoom[socket.userId]

    io.sockets.in('online-users').emit('chat:userLeave', socket.userId);
    console.log('Emitting that users have left to: ', io.sockets.in('online-users'));
    socket.leave('online-users');
  

在 Angular 中,我有两个函数可以发出这两个事件

  this.logout = function(userId) 
      console.log('Logging user out: ', userId);
      Socket.emit('chat:userLogout', userId);
      console.log('Logged out user?');
      delete this.userStore[userId]
    

    this.login = function(userId) 
      console.log('Getting online user ', userId);
      var self = this;
      User.get(id: userId, function(user) 
        self.userStore[userId] = user;
        Socket.emit('chat:userLogin', user);
      );
    

【问题讨论】:

【参考方案1】:

它可能会解决您的问题,但您应该使用 socket.broadcast.to('roomname') 除非您想将消息发送到房间中的所有套接字(包括发送消息的那个)。所以你的代码看起来像

socket.on('chat:userLogin', function(user) 
   socket.join('online-users');
   chatRoom[user.id] = user
   console.log('User Has logged in, chat room contains: ', chatRoom);
   // emit to everyone else except the sender
   socket.broadcast.to('online-users').emit('chat:usersOnline', chatRoom);
)

socket.on('chat:userLogout', function(userId) 
   console.log('User Id ' + userId + 'is logging out');
   delete chatRoom[userId]
   socket.leave('online-users');
   // leaving the chat room here means we can emit to all people in the room
   io.sockets.in('online-users').emit('chat:userLeave', chatRoom);
   console.log('User Has logged out, chat room contains: ', chatRoom);

)

socket.on('disconnect', function() 
   var userRoom = rooms[socket.roomId]

   if (chatRoom[socket.userId])
      delete chatRoom[socket.userId]

   socket.leave('online-users');
   io.sockets.in('online-users').emit('chat:userLeave', socket.userId);

   console.log('Emitting that users have left to: ', io.sockets.in('online-users'));

查看this question 了解更多信息。

【讨论】:

以上是关于Socket.io 不会在断开连接时向房间发送消息的主要内容,如果未能解决你的问题,请参考以下文章

socket.io 下的可靠消息传递?

无法向socket.io中的房间发送消息

如何从客户端断开和重新连接 socket.io?

如何使用nodejs socket.io向特定房间中的用户发送打字警报和消息

使用Socket.io将消息发送到多个房间?

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