【问题标题】:Using rooms with socket.io通过 socket.io 使用房间
【发布时间】:2016-09-08 12:09:04
【问题描述】:

在socket.io 文档中,我看到了一个房间示例

io.on('connection', function(socket){
  socket.on('say to someone', function(id, msg){
    socket.broadcast.to(id).emit('my message', msg);
  });
});

我有一条路线/rooms/:roomId。

是否可以让服务器和客户端之间发送的套接字只命中特定的房间?

我猜服务器应该是这样的

io.on('connection', function(socket){
  socket.on('new msg from client', function(roomId, msg){
    io.to(id).emit('new msg from server', msg);
  });
});

上面和客户端应该发送消息

socket.emit('new msg from client', roomId, msg);

只需使用

即可获得新消息
socket.on('new msg from server', function () {
  document.getElementById('msgs').appendChild(...);
});

但这会奏效吗?我不应该先用socket.join(...) 加入房间吗?

【问题讨论】:

  • 是的,一个套接字需要加入一个房间,然后它会知道进入那个“房间”的所有消息。但是,您可以将 clientID 列表保留在数组中并直接遍历列表。房间是一个很酷的想法,但是有不同的方法可以达到相同的效果。应以示例发布答案。

标签: javascript node.js sockets websocket socket.io


【解决方案1】:

对于我制作的俳句共享应用程序,我有这样的东西:

io.on('connection', function(socket) {
    var socket_id = socket.id;
    var client_ip = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address.address;
    clients.push(socket);
    console.info('New client connected (id=' + socket.id + ').');

    number_of_clients_connected++;
    console.log('[' + client_ip + '] connected, ' + number_of_clients_connected + ' total users online.');

    //when a socket is disconnected or closed, .on('disconnect') is fired
    socket.on('disconnect', function() {
        number_of_clients_connected--;
        console.log('[' + client_ip + '] disconnected, ' + number_of_clients_connected + ' total users online.');
        //on disconnect, remove from clients array
        var index = clients.indexOf(socket);
        if (index != -1) {
            clients.splice(index, 1);
            //console.info('Client gone (id=' + socket.id + ').');
        }
    });

因此它保留了一组客户端,当某些消息需要中继时,您可以指定客户端套接字 ID...

//reads from latest_haikus_cache and sends them
socket.on('request_haiku_cache', function() {
    latest_haikus_cache.forEach(function(a_latest_haiku) {
        clients[clients.indexOf(socket)].emit('load_haiku_from_cache', a_latest_haiku);
    });
});

【讨论】:

  • 那么,这如何回答这个问题?
  • 提供了一种不同的方法。提问者想向特定的客户发送消息,而房间——尽管在 socket.io 中是个好主意——并不是我最终使用的
【解决方案2】:

允许服务器向任何房间广播,因此您可以支持让客户端请求服务器发送到房间,而该客户端不在房间内。这真的取决于你想做什么。

因此,如果您希望您的服务器具有允许任何客户端向他们选择的任何房间发送消息的代码:

io.on('connection', function(socket){
  socket.on('new msg from client', function(roomId, msg){
    io.to(roomId).emit('new msg from server', msg);
  });
});

那么,你确实可以做到这一点,它会奏效的。是否合适完全取决于您的应用程序以及您是否希望任何客户端能够向其名称所在的任何房间广播。

但这会起作用吗?

是的,它会起作用的。

我不应该先用 socket.join(...) 加入房间吗?

除非客户端想要接收该房间的消息,否则无需让客户端加入房间。如果你想这样做,你不必在房间里要求服务器发送到那个房间。所以,这一切完全取决于您的应用程序以及什么是合适的。

我有一条路线 /rooms/:roomId。

是否可以使套接字在服务器和服务器之间发送 客户只打特定的房间?

我无法弄清楚您问题的这一部分是什么意思。如果您愿意进一步解释,我也会尽力帮助您完成这部分。

【讨论】:

  • 当客户端进入路由/rooms/:roomId 上的房间时,我从数据库中检索属于此roomId 的所有消息。当客户端仍在此URL 上而不更新页面时,我希望它使用socket.io 检索新消息。但我只希望客户端检索专门发送到这个房间(而不是所有其他房间)的消息。所以在客户端,我在发射时也附上了roomId。现在我想告诉服务器只向那些当前在roomId 所属房间中的客户端发送新消息。
  • @Jamgreen - 如果您将所需的房间 ID 与您的客户端 .emit() 一起发送,那么服务器将收到该参数并可以使用它来知道从哪个房间获取消息,就像您所说的那样我知道。您需要什么帮助?
  • 当我从服务器发送到客户端时,我使用的是所有客户端都接收到的io.sockets.emit('hi clients from the server');。我只希望给定roomId 中的客户端从服务器接收消息。所以我希望能够使用io.to('some room id').sockets.emit('hi clients in this room from the server'); 将此消息发送给仅在路由/rooms/:roomId 上连接的那些客户端。
  • 使用socket.emit() 仅发送到您刚刚收到消息的socket。
  • 但我想发送到所有连接到 url 的套接字(带有特定的房间 id)。
猜你喜欢
  • 2020-01-10
  • 2017-10-20
  • 2018-02-20
  • 2019-05-13
  • 1970-01-01
  • 2016-05-08
  • 2019-03-02
  • 2011-12-02
  • 1970-01-01
相关资源
最近更新 更多