web-dev-qa-db-fra.com

Socket.io: espaces de noms, canaux & co

J'ai un serveur Web Node.js qui exécute un serveur de socket sur le dessus, qui a été créé en utilisant Socket.io . Fondamentalement, cela fonctionne.

Ce que je veux maintenant réaliser, c'est que les clients qui se connectent sont regroupés en groupes. Il peut donc y avoir des clients qui composent le groupe A et d'autres clients qui composent le groupe B. Ils doivent sélectionner à quel groupe ils appartiennent en adressant une URL spécifique, soit localhost:3000/A Ou localhost:3000/B.

Dans Socket.io, je veux maintenant envoyer des messages à tous les clients du groupe A ou à tous les clients du groupe B ou à tous les clients, sans regarder leur groupe.

C'est essentiellement comme avoir une conversation avec des salles, et vous avez soit des messages pour tous les clients dans une salle spécifique, soit pour n'importe quel client, quelle que soit la pièce dans laquelle il se trouve.

Quelle est la meilleure façon de concevoir un tel système en utilisant Socket.io?

J'ai essayé d'utiliser l'espace de noms jusqu'à présent, ce qui fonctionne essentiellement pour créer les groupes A et B, mais j'ai perdu la possibilité d'envoyer des messages à tous les clients, quelle que soit la pièce dans laquelle ils se trouvent. Au moins, je ne sais pas comment faire ce.

Comment dois-je modéliser cela? Quels sont les bons termes à rechercher?

MISE À JOUR: Selon la réponse de @ sdedelbrock je pourrais utiliser l'espace de noms ou les salles:

  • Si j'utilise des espaces de noms, je ne suis plus en mesure d'envoyer à tout le monde, quel que soit leur espace de noms. En effet, io.sockets Est un raccourci vers io.of(''), qui bien sûr ne correspond plus à l'espace de noms.
  • Cela signifie que je devrais utiliser des pièces, mais je me demande quelle est la différence sémantique entre une pièce et un espace de noms.

Pour faire court: pourquoi y a-t-il deux concepts pour la même (?) Idée?

29
Golo Roden

Vous pourriez utiliser des pièces de sorte que vous fassiez ce qui suit pour émettre à tout le monde dans une pièce

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

Ensuite, pour émettre à tout le monde, vous pouvez utiliser

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

Vous pouvez également utiliser des espaces de noms:

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

Pour émettre à tout le monde sauf l'utilisateur qui vous a déclenché, vous utiliseriez:

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

[modifier] Voici une réponse plus détaillée:

L'idée derrière l'espacement des noms est qu'il est géré séparément des autres espaces de noms (même globaux). Considérez-le comme s'il s'agissait d'une toute nouvelle instance socket.io, vous pouvez exécuter de nouvelles poignées de main, de nouveaux événements, des autorisations, etc. sans que les différents espaces de noms interfèrent les uns avec les autres.

Ce serait utile pour dire /chat et /tracking où l'événement de connexion aurait une logique très différente

Socket.io fait tout le travail pour vous comme s'il s'agissait de deux instances distinctes, mais limite toujours les informations à une seule connexion, ce qui est assez intelligent.

Il peut y avoir une solution de contournement dans laquelle vous pouvez diffuser vers tous les espaces de noms (exemple ci-dessous). Mais en bref, vous ne devriez pas faire cela, vous devriez utiliser les chambres.

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

Il s'agit d'un modèle d'application que vous pouvez utiliser (fonctionne pour 9.16; non testé sur 1.x mais cela devrait fonctionner):

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

Vous pouvez écrire d'autres poignées par vous-même :)

4
Marwen Trabelsi