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

Posted

技术标签:

【中文标题】socket.io - 如何在命名空间上广播消息?【英文标题】:socket.io - how to broadcast messages on a namespace? 【发布时间】:2011-09-22 14:17:15 【问题描述】:

根据socket.io示例:

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

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);
      );
  );

但现在情况更糟——没有人收到消息,甚至发件人也没有。无论如何,这是我合乎逻辑的预期 - 一个套接字不能通过自身广播某些内容。这次也没有例外,所以为socket定义了广播。

如果我这样做:

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

那么只有原始发送者会收到消息,这又是非常合乎逻辑的——我使用了客户端相关套接字的“发送”。

那么问题来了:使用广播功能的正确方法是什么?

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

【问题讨论】:

你试过chat.socket.broadcast吗? @Raynos:感谢您的想法,但仍然 chat.socket.broadcast.send 和 chat.socket.broadcast 抛出未定义的异常。 【参考方案1】:

似乎我能够在打开赏金后自己解决这个问题。对此感到抱歉。

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

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
  );
);

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

【讨论】:

如果你使用io.sockets.emit('signal', obj) 会向所有人发送信号 这个例子应该在 Socket.IO 文档的顶部附近。大多数应用程序需要独立回复每个连接,而不是总是无条件地向所有监听器广播! 使用此代码,您可以将消息发送到命名空间中的所有套接字,而不仅仅是特定房间的套接字。我说的对吗? 我不明白。您在问题中说,这个确切的代码减去socket.emit(msg);,导致没有人收到消息。为什么添加socket.emit(msg); 会突然导致socket.broadcast.emit(msg); 将消息发送给除发件人之外的所有人?【参考方案2】:

如果您在来自客户端的消息触发对所有其他人的响应的事件环境中工作,则您的解决方案有效,但如果您希望服务器向所有客户端发送消息,则该解决方案无效。

您可以使用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!" );

【讨论】:

对我来说,这听起来有点像混淆了套接字的namespaceroom 的术语。哪些是分开处理的。对于那些寻找广播到特定房间(从服务器)的人来说,语法是io.sockets.in('room name').emit 我不明白这是如何回答这个问题的......问题是如何广播一条消息,你的回答将消息发送给已经在 OPs 代码中工作的每个人 只是作为一个更新 - 向所有客户端发出的服务器直到在文档中没有具体说明。当你玩它的时候你会弄明白的,但是如何使用 .emit 并不是很直观。他们的文档确实需要添加更多示例才能点击。 在这里为我节省了很多时间! 'sockets' vs io.of()【参考方案3】:

也许这会对某人有所帮助

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

Nodejs and Socketio Multiroom Chat Tutorial

【讨论】:

【参考方案4】:
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)

【讨论】:

将聊天更改为 customNS

以上是关于socket.io - 如何在命名空间上广播消息?的主要内容,如果未能解决你的问题,请参考以下文章

Socket.IO:如何删除命名空间

Socket.io 命名空间限制以及如何扩展它

socket io 广播、房间和确认功能

socket io 广播、房间和确认功能

在 MEAN.js 4.2 中使用 Socket.io 命名空间

动态命名空间 Socket.IO