tutorial socket rooms example node.js namespaces socket.io channel

node.js - rooms - socket.io example



Socket.io: Espacios de nombres, canales y co (2)

Tengo un servidor web Node.js que ejecuta un servidor de socket en la parte superior, que se creó utilizando Socket.io . Básicamente, esto funciona.

Lo que ahora quiero lograr es que los clientes que se conectan se agrupen en grupos. Así que puede haber algunos clientes que conforman el grupo A y otros clientes que conforman el grupo B. Deberán seleccionar a qué grupo pertenecen dirigiéndose a una URL específica, ya sea localhost:3000/A o localhost:3000/B

En Socket.io ahora quiero enviar mensajes a todos los clientes del grupo A o a todos los clientes del grupo B o a todos los clientes, sin mirar a su grupo.

Básicamente es como tener un chat con salas, y tienes mensajes para todos los clientes dentro de una sala específica, o para cualquier cliente, sin importar en qué sala se encuentre.

¿Cuál es la mejor manera de diseñar un sistema de este tipo utilizando Socket.io?

He intentado usar el espacio de nombres hasta ahora, lo que básicamente funciona para crear los grupos A y B, pero luego pierdo la capacidad de enviar mensajes a todos los clientes, sin importar en qué espacio se encuentren. Al menos no sé cómo hacerlo. esta.

¿Cómo debo modelar esto? ¿Cuáles son los términos correctos que debo buscar?

ACTUALIZACIÓN: De acuerdo con la respuesta de @sdedelbrock , podría usar espacios de nombres o habitaciones:

  • Si utilizo espacios de nombres, no puedo enviarlos a todos, independientemente de su espacio de nombres. Esto se debe a que io.sockets es un acceso directo a io.of('''') , que por supuesto ya no coincide con el espacio de nombres.
  • Esto significa que debería usar habitaciones, pero me pregunto cuál es la diferencia semántica entre una habitación y un espacio de nombres.

Para abreviar: ¿Por qué hay dos conceptos para la misma idea (?)?


Esta es una aplicación de plantilla que puede usar (funciona para 9.16; no se probó en 1.x pero debería funcionar):

var namespaces = [ io.of(''/ns1''), io.of(''/ns2''), io.of(''/ns3'') ]; for (i in namespaces) { namespaces[i].on(''connection'',handleConnection(namespaces[i])); } function handleConnection(ns) { return function (socket){ //connection console.log("connected "); socket.on(''setUsername'',setUsernameCallback(socket,ns)); socket.on(''disconnect'', disconnectCallback(socket,ns)); socket.on(''messageChat'',messageChatCallback(socket,ns)); socket.on(''createJoinRoom'',createJoinRoomCallback(socket,ns)); }; } function disconnectCallback(socket,ns) { return function(msg){ console.log("Disconnected "); socket.broadcast.send("It works!"); }; }

Podrías escribir otros manejadores por ti mismo :)


Podría estar usando habitaciones, por lo que haría lo siguiente para emitir a todos en una habitación

io.sockets.in(''a'').emit(''inA'', ''foo'')

Luego, para emitir a todo el mundo que puedas usar.

io.sockets.emit(''everyone'',''bar'');

También puede utilizar espacios de nombres también:

io.of(''/b'').emit(''inB'', ''buzz'');

Para emitir a todos, excepto al usuario que lo activó, usarías:

io.sockets.broadcast.emit("hello");

[editar] Aquí hay una respuesta más detallada:

La idea detrás del espacio entre nombres es que se maneja por separado de los otros espacios de nombres (incluso global). Piense en ello como si fuera una instancia completamente nueva de socket.io, puede ejecutar nuevos handshakes, nuevos eventos, autorizaciones, etc. sin que los diferentes espacios de nombres interfieran entre sí.

Esto sería útil para decir /chat /tracking donde el evento de conexión tendría una lógica muy diferente

Socket.io hace todo el trabajo por usted como si fueran dos instancias separadas, pero aún así limita la información a una conexión, lo cual es bastante inteligente.

Puede haber una solución alternativa en la que se pueda transmitir a todos los espacios de nombres (ejemplo a continuación). Sin embargo, en resumen, no deberías estar haciendo esto, deberías usar habitaciones.

for (var nameSpace in io.sockets.manager.namespaces){ io.of(nameSpace).emit("messageToAll", message); }