2012-11-22 19 views
28

Ho un server web Node.js che esegue un server socket in alto, che è stato creato usando Socket.io. Fondamentalmente, questo funziona.Socket.io: Namespace, canali & co

Quello che ora voglio ottenere è che i client che si connettono sono raggruppati in gruppi. Quindi potrebbero esserci alcuni client che costituiscono il gruppo A e altri client che costituiscono il gruppo B. Devono selezionare a quale gruppo appartengono indirizzando un URL specifico, localhost:3000/A o localhost:3000/B.

In Socket.io ora desidero inviare messaggi a tutti i client nel gruppo A oa tutti i client nel gruppo B oa tutti i client, senza guardare il loro gruppo.

E 'praticamente come avere una chiacchierata con camere, e si dispone di entrambi i messaggi per tutti i clienti all'interno di una stanza specifica, o per qualsiasi cliente, non importa quale stanza in cui si trova.

Qual è il modo migliore per progettare un tale sistema che usa Socket.io?

Ho cercato di utilizzare lo spazio dei nomi finora, che funziona fondamentalmente per la creazione dei gruppi A e B, ma poi perdo la possibilità di inviare messaggi a tutti i client, indipendentemente dalla stanza in cui si trovano. Almeno io non sapere come fare questo

Come devo modellare questo? Quali sono i termini giusti che dovrei cercare?

UPDATE: Secondo la risposta di @sdedelbrock potrei usare namespace o camere:

  • Se uso spazi dei nomi, io non sono a lungo in grado di inviare a tutti, indipendentemente dalla loro spazio dei nomi. Questo perché io.sockets è una scorciatoia per io.of(''), che ovviamente non corrisponde più allo spazio dei nomi.
  • Ciò significa che dovrei usare le stanze, ma mi chiedo quale sia la differenza semantica tra una stanza e uno spazio dei nomi.

Per farla breve: perché ci sono due concetti per la stessa (?) Idea?

risposta

29

si potrebbero utilizzare le camere in modo che avrebbe effettuare le seguenti operazioni per emettere a tutti in una stanza

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

Poi per emettere a tutti è possibile utilizzare

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

È inoltre possibile utilizzare gli spazi dei nomi come Bene:

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

Per emettere a tutti tranne che l'utente che ha attivato l'utente avrebbe utilizzato:

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

[modifica] Ecco una risposta più dettagliata:

L'idea alla base di nome-spacing è che è gestita separatamente dagli altri spazi dei nomi (anche mondiale). Consideralo come se fosse un'istanza socket.io completamente nuova, puoi eseguire nuovi handshake, nuovi eventi, autorizzazioni, ecc. Senza che i diversi namespace interferiscano tra loro.

Questo sarebbe utile per dire /chat e /tracking dove l'evento di connessione avrebbe logica molto diversa

Socket.io fa tutto il lavoro per voi, come se si tratta di due istanze separate, ma comunque limita le informazioni ad un connessione, che è abbastanza intelligente.

Potrebbe esserci una soluzione alternativa in cui è possibile trasmettere a tutti gli spazi dei nomi (esempio di seguito). Tuttavia, in breve, non dovresti farlo, dovresti usare le stanze.

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

Ho provato questo. Quando si utilizza il secondo approccio (namespace), non sono in grado di inviare a tutti, indipendentemente dal loro spazio dei nomi. Questo perché 'io.sockets' è una scorciatoia per' io.of ('') ', che ovviamente non corrisponde più allo spazio dei nomi. Quindi questo significa che dovrei usare le stanze. In ogni caso, mi chiedo quale sia la differenza semantica tra una stanza e uno spazio dei nomi? Perché ci sono due concetti per la stessa (?) Idea? –

+1

Credo che sia così che possano essere gestiti separatamente, ho trovato comunque una buona scrittura su [Socket.io Namespaces] (http://gordonkoo.com/blog/2012/02/28/under-the-hood -of-socket-io-namespace /) – Sdedelbrock

+0

Questo articolo è sicuramente una buona lettura, ma sfortunatamente non risponde alla mia domanda. Continuo a non capire quando dovrei usare gli spazi dei nomi, quando stanze, e quale è la differenza semantica tra loro. Inoltre, come faccio a inviare un messaggio a tutti i client, indipendentemente dal loro spazio dei nomi? –

4

Questo è un modello di applicazione è possibile utilizzare (lavora per 9,16; non testato su 1.x ma dovrebbe funzionare):

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

Si potrebbe scrivere altre maniglie da soli :)