socket.io - 如何在命名空间上广播消息?

时间:2011-06-25 12:39:32

标签: node.js broadcast socket.io

根据socket.io示例:

  

要进行广播,只需向broadcastemit方法调用添加send标记即可。广播意味着向除了启动它的套接字以外的所有人发送消息。

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.broadcast.emit('user connected');
});

我试图将它与新的socket.io namsepace功能结合起来,所以我得到了这个:

var chat = ioserver.of('/chat');

chat.on('connection', function (socket) {
      console.log('chat connection');   
      socket.on('message', function (msg) {
        console.log(msg);  
        chat.send(msg);
      });
  });

这很好用,聊天频道(没有其他频道)的每个人都收到消息。但发件人也得到了它。 所以我尝试做以下事情:

chat.on('connection', function (socket) {
      console.log('chat connection');   
      socket.on('message', function (msg) {
        console.log(msg);  
        chat.broadcast.send(msg);
      });
  });

并得到一个例外:'无法调用方法'发送'未定义。' 好吧,所以我想,广播是单个套接字的特性(虽然它感觉有点奇怪 - 单个套接字如何能够与其他套接字交换......)。  所以我试过了:

chat.on('connection', function (socket) {
      console.log('chat connection');   
      socket.on('message', function (msg) {
        console.log(msg);  
        socket.broadcast.send(msg);
      });
  });

但现在情况更糟 - 没有人收到消息,甚至没有发送者。无论如何,这是我逻辑上所期望的 - 一个套接字无法通过自身广播。这次没有例外,因此为套接字定义了广播。

如果我这样做:

chat.on('connection', function (socket) {
      console.log('chat connection');   
      socket.on('message', function (msg) {
        console.log(msg);  
        socket.send(msg);
      });
  });

然后只有原始发件人获取消息,这又是非常合乎逻辑的 - 我使用了与客户端相关的套接字的“发送”。

所以问题是:使用广播功能的正确方法是什么?

也许socket.io的开发人员犯了一个错误并将广播功能添加到错误的对象中(据我所知,它应该是命名空间的功能,但现在只为套接字定义)?

4 个答案:

答案 0 :(得分:70)

似乎我在打开赏金后能够为自己解决这个问题。对不起。

无论如何,看看这是否有帮助:

chat.on('connection', function (socket) {
  socket.on('message', function (msg) {
    socket.emit(msg); // Send message to sender
    socket.broadcast.emit(msg); // Send message to everyone BUT sender
  });
});

但是,如果您不将重新发送给发件人,则可以为用户节省一些带宽并创建更快捷的体验。只需将他们的消息直接添加到聊天记录中,并可选择仅使用自我发射来确认收到的消息没有问题。

答案 1 :(得分:35)

如果您在一个公共环境中工作,您的解决方案可以正常工作,其中来自客户端的消息会触发对所有其他客户的响应,但如果您希望服务器向所有客户端发送消息,则无法解决此问题。

您可以使用io.sockets.emit

执行此操作
var io = require('socket.io').listen(80);
io.sockets.emit('message', { message: "Hello everyone!" });

但是,文档不清楚如何对特定命名空间执行此操作。 io.sockets只是io.of('')的快捷方式,因此您可以通过调用io.of('/namespace').emit向命名空间中的每个人广播:

var io = require('socket.io').listen(80);
io.of('/admins').emit('message', { message: "Hello admins!" });

答案 2 :(得分:28)

var customNS = ioserver.of('/chat'); 

customNS.on('connection', function (socket) {
   socket.on('message', function (msg) {

       // Send message to sender 
       socket.emit(msg);

       // Send message to everyone on customNS INCLUDING sender
       customNS.emit(msg);

       // Send message to everyone on customNS BUT sender
       socket.broadcast.emit(msg);

       // Send message to everyone on ROOM chanel of customNS INCLUDING sender
       customNS.in('ROOM').emit(msg); 

       // Send message to everyone on ROOM chanel of customNS BUT sender
       socket.broadcast.in('ROOM').emit(msg); 


   });
});

同时查看此答案Send response to all clients except sender (Socket.io)

答案 3 :(得分:14)

也许这会帮助某人

socket.broadcast.to('room1').emit('updatechat', 'SERVER', username + ' has connected to this room'); 

Nodejs and Socketio Multiroom Chat Tutorial