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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6477770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 14:19:10  来源:igfitidea点击:

socket.io - how to broadcast messages on a namespace?

node.jsbroadcastsocket.io

提问by JustAMartin

According to socket.io examples:

根据 socket.io 示例:

To broadcast, simply add a broadcastflag to emitand sendmethod calls. Broadcasting means sending a message to everyone else except for the socket that starts it.

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

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

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

I tried to combine this with the new socket.io namsepace feature, so I got this:

我试图将它与新的 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);
      });
  });

This works fine, everyone on the chat channel (and no other channels) gets the message. But the sender also gets it. So I tried to do the following:

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

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

and got an Exception: 'Cannot call method 'send' of undefined.' Ok, so I thought, that broadcast is the feature of a single socket (it feels a bit weird though - how a single socket can brodacast to all other...). So I tried:

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

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

but now it was even worse - no one received the message, not even the sender. Anyway, it was what I logically expected - one socket cannot broadcast something through itself. And no exceptions this time, so broadcast is defined for the socket.

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

If I do:

如果我做:

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

then only the original sender gets the message, and that is again pretty logical - I used the 'send' of the client-related socket.

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

So the question is: what is the correct way to use the broadcast feature?

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

Maybe the developer of socket.io made a mistake and added the broadcast feature to the wrong object (as I understand, it should be the feature of the namespace but now it is defined only for the socket)?

可能是socket.io的开发者搞错了,把broadcast特性加到了错误的对象上(我理解应该是namespace的特性,但现在只为socket定义了)?

回答by

Seems I was able to solve this for myself after opening a bounty. Sorry about that.

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

Anyway, see if this helps:

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

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

However, you could save some bandwidth and create a more snappy experience for users if you don't resend it to the sender. Just add their messages directly to the chat log, and optionally use use only self-emit to confirm it was received without issue.

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

回答by Luca Spiller

You solution works if you are working in an evented environment where messages from the client trigger a response to all others, but not if you want the server to sent messages to all clients.

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

You can do this using io.sockets.emit:

您可以使用io.sockets.emit以下方法执行此操作:

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

However the documentation isn't clear for how to do this to a specific namespace. io.socketsis just a shortcut to io.of(''), as such you can broadcast to everyone on a namespace by calling io.of('/namespace').emit:

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

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

回答by smbeiragh

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


   });
});

also check this answer Send response to all clients except sender (Socket.io)

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

回答by Shimon Doodkin

Maybe this will help someone

也许这会帮助某人

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

see

Nodejs and Socketio Multiroom Chat Tutorial

Nodejs 和 Socketio 多房间聊天教程