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

Jus*_*tin 48 broadcast node.js socket.io

根据socket.io示例:

要广播,只需添加一个broadcast标志emitsend方法调用.广播意味着向除了启动它的套接字之外的所有人发送消息.

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

io.sockets.on('connection', function (socket) {
  socket.broadcast.emit('user connected');
});
Run Code Online (Sandbox Code Playgroud)

我试图将它与新的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);
      });
  });
Run Code Online (Sandbox Code Playgroud)

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

chat.on('connection', function (socket) {
      console.log('chat connection');   
      socket.on('message', function (msg) {
        console.log(msg);  
        chat.broadcast.send(msg);
      });
  });
Run Code Online (Sandbox Code Playgroud)

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

chat.on('connection', function (socket) {
      console.log('chat connection');   
      socket.on('message', function (msg) {
        console.log(msg);  
        socket.broadcast.send(msg);
      });
  });
Run Code Online (Sandbox Code Playgroud)

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

如果我做:

chat.on('connection', function (socket) {
      console.log('chat connection');   
      socket.on('message', function (msg) {
        console.log(msg);  
        socket.send(msg);
      });
  });
Run Code Online (Sandbox Code Playgroud)

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

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

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

小智 71

似乎在打开赏金后我能够为自己解决这个问题.对于那个很抱歉.

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

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

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

  • 如果你使用`io.sockets.emit('signal',obj)`将信号发送给每个人 (11认同)
  • 我不明白.你在问题中说,这个确切的代码,减去`socket.emit(msg);`,导致**没有人**接收消息.为什么添加`socket.emit(msg);`突然导致`socket.broadcast.emit(msg);`将消息发送给除发件人之外的所有人? (3认同)

Luc*_*ler 36

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

你可以这样做io.sockets.emit:

var io = require('socket.io').listen(80);
io.sockets.emit('message', { message: "Hello everyone!" });
Run Code Online (Sandbox Code Playgroud)

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

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

  • 对我来说,这听起来有点像混淆了套接字的“命名空间”和“房间”这两个术语。哪些是分开处理的。对于那些寻求向特定房间(从服务器)广播的人,语法为“io.sockets.in('房间名称').emit” (2认同)

smb*_*agh 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); 


   });
});
Run Code Online (Sandbox Code Playgroud)

还检查此答案发送响应除发件人以外的所有客户端(Socket.io)


Shi*_*kin 14

也许这会对某人有所帮助

socket.broadcast.to('room1').emit('updatechat', 'SERVER', username + ' has connected to this room'); 
Run Code Online (Sandbox Code Playgroud)

看到

Nodejs和Socketio多房间聊天教程