socket.io:向特定房间发送消息(客户端)

时间:2022-03-22 07:37:42

In socket.io, you usually use a specific syntax on the server side if you want to send a message to a specific room: io.to(room).emit('event', 'message');.

在socket.io中,如果要将消息发送到特定房间,通常在服务器端使用特定语法:io.to(room).emit('event','message');.

But how would a client (what I mean is the socket.io-related code running in a browser) indicate that a message should go to a specific room?

但客户端(我的意思是在浏览器中运行的socket.io相关代码)如何表明消息应该转到特定的房间?

Is it common to just create something like this (of course the server has to evaluate it):

只创建这样的东西是常见的(当然服务器必须对其进行评估):

socket.emit('chat message', {room: 'abc', msg: 'hello there'});

Or does the socket.io client-side library offer a specific syntax for this purpose as well?

或者socket.io客户端库是否也为此提供了特定的语法?

edit: to clarify, my suggestion from above seems to work, I'm just not sure if there's a better solution.

编辑:澄清一下,我上面的建议似乎有效,我只是不确定是否有更好的解决方案。

2 个解决方案

#1


17  

You've pretty much figured it out. Only the server can emit to specific rooms, because it is only the server that is actually connected to multiple clients. In other words, clients aren't connected to each other — the client-side library only manages communications between that one client and the server. So, if you want your client app to instruct the server to emit a message to all clients connected to a given room… that's basic API design. You could emit a socket event, or just do a regular http call to a route on your server. Either way you'll be sending metadata about which room(s) the server should broadcast to. The former (emitting) is probably preferred however, because that way on the server side you can use socket.broadcast.to to emit to all clients in the room EXCEPT the socket that initiated the call (a pretty common use case).

你已经弄明白了。只有服务器可以向特定房间发射,因为它只是实际连接到多个客户端的服务器。换句话说,客户端没有相互连接 - 客户端库只管理该客户端和服务器之间的通信。因此,如果您希望您的客户端应用程序指示服务器向连接到给定房间的所有客户端发送消息...这是基本的API设计。您可以发出套接字事件,或只是对服务器上的路由进行常规http调用。无论哪种方式,您都将发送有关服务器应广播到哪个房间的元数据。然而,前者(发射)可能是首选,因为在服务器端,您可以使用socket.broadcast.to向房间中的所有客户端发出除了发起调用的套接字(一个非常常见的用例)。

#2


2  

Alapeno's solution was for the client to send a specific room as part of the message data to the server, so that the server would know which room to broadcast the message to.

Alapeno的解决方案是让客户端将特定房间作为消息数据的一部分发送到服务器,以便服务器知道将消息广播到哪个房间。

However, if you just want the client to send a message to its own room, you can have the server detect the client's room on its own via the socket.rooms object. Thus, you wouldn't need the client to send the name of its room as part of the message as you indicated.

但是,如果您只是希望客户端将消息发送到自己的房间,您可以让服务器通过socket.rooms对象自行检测客户端的房间。因此,您不需要客户端将其房间名称作为您指示的消息的一部分发送。

Client.js:

Client.js:

socket.emit('chat message', 'hello');

Server.js:

Server.js:

socket.on('chat message', function(msg){
    var keys = Object.keys(socket.rooms);
    for (var i = 0; i < keys.length; i++) {
        io.to(socket.rooms[keys[i]]).emit('chat message', msg);
    }
});

Update: The socket.rooms object includes a sort of hash such as the example below, thus you'd better send to all the rooms in the socket.rooms to be sure the room members receive it. You can't be guaranteed the ordering of the keys.

更新:socket.rooms对象包含一种哈希,如下面的示例,因此您最好发送到socket.rooms中的所有房间,以确保房间成员收到它。您无法保证钥匙的订购。

Example:

例:

socket.rooms[keys[0]]) = WMWlX-ekAxa8hP8FAAAE

socket.rooms [keys [0]])= WMWlX-ekAxa8hP8FAAAE

socket.rooms[keys[1]]) = app-chat-room

socket.rooms [keys [1]])= app-chat-room

#1


17  

You've pretty much figured it out. Only the server can emit to specific rooms, because it is only the server that is actually connected to multiple clients. In other words, clients aren't connected to each other — the client-side library only manages communications between that one client and the server. So, if you want your client app to instruct the server to emit a message to all clients connected to a given room… that's basic API design. You could emit a socket event, or just do a regular http call to a route on your server. Either way you'll be sending metadata about which room(s) the server should broadcast to. The former (emitting) is probably preferred however, because that way on the server side you can use socket.broadcast.to to emit to all clients in the room EXCEPT the socket that initiated the call (a pretty common use case).

你已经弄明白了。只有服务器可以向特定房间发射,因为它只是实际连接到多个客户端的服务器。换句话说,客户端没有相互连接 - 客户端库只管理该客户端和服务器之间的通信。因此,如果您希望您的客户端应用程序指示服务器向连接到给定房间的所有客户端发送消息...这是基本的API设计。您可以发出套接字事件,或只是对服务器上的路由进行常规http调用。无论哪种方式,您都将发送有关服务器应广播到哪个房间的元数据。然而,前者(发射)可能是首选,因为在服务器端,您可以使用socket.broadcast.to向房间中的所有客户端发出除了发起调用的套接字(一个非常常见的用例)。

#2


2  

Alapeno's solution was for the client to send a specific room as part of the message data to the server, so that the server would know which room to broadcast the message to.

Alapeno的解决方案是让客户端将特定房间作为消息数据的一部分发送到服务器,以便服务器知道将消息广播到哪个房间。

However, if you just want the client to send a message to its own room, you can have the server detect the client's room on its own via the socket.rooms object. Thus, you wouldn't need the client to send the name of its room as part of the message as you indicated.

但是,如果您只是希望客户端将消息发送到自己的房间,您可以让服务器通过socket.rooms对象自行检测客户端的房间。因此,您不需要客户端将其房间名称作为您指示的消息的一部分发送。

Client.js:

Client.js:

socket.emit('chat message', 'hello');

Server.js:

Server.js:

socket.on('chat message', function(msg){
    var keys = Object.keys(socket.rooms);
    for (var i = 0; i < keys.length; i++) {
        io.to(socket.rooms[keys[i]]).emit('chat message', msg);
    }
});

Update: The socket.rooms object includes a sort of hash such as the example below, thus you'd better send to all the rooms in the socket.rooms to be sure the room members receive it. You can't be guaranteed the ordering of the keys.

更新:socket.rooms对象包含一种哈希,如下面的示例,因此您最好发送到socket.rooms中的所有房间,以确保房间成员收到它。您无法保证钥匙的订购。

Example:

例:

socket.rooms[keys[0]]) = WMWlX-ekAxa8hP8FAAAE

socket.rooms [keys [0]])= WMWlX-ekAxa8hP8FAAAE

socket.rooms[keys[1]]) = app-chat-room

socket.rooms [keys [1]])= app-chat-room