2012-11-22 11 views
28

Mam serwer Node.js, który uruchamia serwer gniazd na górze, który został utworzony przy użyciu Socket.io. Zasadniczo to działa.Socket.io: Przestrzenie nazw, kanały i co

Co chcę teraz osiągnąć, to że klienci, którzy łączą się, są zgrupowani w grupy. Tak więc mogą istnieć klienci, którzy tworzą grupę A i inni klienci, którzy tworzą grupę B. Będą wybierać do której grupy należą, podając adres URL, albo localhost:3000/A lub localhost:3000/B.

W Socket.io chcę teraz wysyłać wiadomości do wszystkich klientów w grupie A lub do wszystkich klientów w grupie B lub do wszystkich klientów, nie patrząc na ich grupę.

Jest to w zasadzie jak o rozmowę z pokoi i trzeba albo wiadomości dla wszystkich klientów w określonym pomieszczeniu, lub dla każdego klienta, bez względu na to, co pokoju jest on w.

Jaki jest najlepszy sposób projektowania taki system za pomocą Socket.io?

Próbowałem dotychczas używać przestrzeni nazw, która zasadniczo służy do tworzenia grup A i B, ale wtedy tracę możliwość wysyłania wiadomości do wszystkich klientów, bez względu na to, w którym pokoju się znajdują. Przynajmniej ja nie wiem, jak to zrobić.

Jak mam to modelować? Jakie są właściwe określenia, których powinienem szukać?

UPDATE: Zgodnie z odpowiedzią @sdedelbrock mogę użyć nazw lub pokoi:

  • W przypadku używania nazw, nie jestem długo w stanie wysłać do wszystkich, niezależnie od ich nazw. Dzieje się tak, ponieważ io.sockets jest skrótem do io.of(''), co oczywiście nie pasuje już do przestrzeni nazw.
  • Oznacza to, że powinienem używać pokoi, ale zastanawiam się, czym jest semantyczna różnica między pokojem a przestrzenią nazw.

Krótko mówiąc: dlaczego istnieją dwie koncepcje dotyczące tego samego (?) Pomysłu?

Odpowiedz

29

można być za pomocą pokoje więc można wykonać następujące czynności, aby emitować do wszystkich w pomieszczeniu

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

Następnie emitować wszystkim można użyć

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

Można również użyć nazw jako cóż:

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

Aby emitować do wszystkich użytkowników poza uruchomionym użytkownikiem, należy użyć:

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

[edytuj] Tutaj jest bardziej szczegółowa odpowiedź:

Ideą imienin odstępów jest to, że jest obsługiwane oddzielnie od innych nazw (nawet globalnej). Pomyśl o tym, jakby była to zupełnie nowa instancja socket.io, możesz uruchamiać nowe uściski dłoni, nowe zdarzenia, autoryzacje itp. Bez wzajemnego zakłócania różnych przestrzeni nazw.

Byłoby to przydatne dla powiedzmy /chat i /tracking gdzie zdarzenie połączenia miałby zupełnie inną logikę

Socket.io wykonuje całą pracę za ciebie, jak gdyby to dwa odrębne przypadki, ale nadal ogranicza informacje do jednego połączenie, które jest całkiem sprytne.

Może istnieć obejście, w którym można transmitować do wszystkich przestrzeni nazw (przykład poniżej). Krótko mówiąc nie powinieneś tego robić, powinieneś używać pokoi.

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

Próbowałem tego. Korzystając z drugiego podejścia (przestrzeni nazw), nie mogę długo wysyłać do wszystkich, niezależnie od ich przestrzeni nazw. Dzieje się tak, ponieważ 'io.sockets' jest skrótem do' io.of ('') ', co oczywiście nie pasuje już do przestrzeni nazw. Oznacza to, że powinienem korzystać z pokoi. W każdym razie, zastanawiam się, co oznacza różnica semantyczna między pokojem a przestrzenią nazw? Dlaczego istnieją dwa pojęcia dotyczące tego samego (?) Pomysłu? –

+1

Uważam, że jest tak, że można nimi zarządzać osobno, znalazłem dobry napis na ten temat, chociaż [Socket.io Namespaces] (http://gordonkoo.com/blog/2012/02/28/under-the-hood) -of-socket-io-namespaces /) – Sdedelbrock

+0

Ten artykuł jest zdecydowanie dobry, ale niestety nie odpowiada na moje pytanie. Nadal nie rozumiem, kiedy powinienem używać przestrzeni nazw, pomieszczeń i jaka jest między nimi różnica semantyczna. Co więcej: Jak wysłać wiadomość do wszystkich klientów, niezależnie od ich przestrzeni nazw? –

4

Jest to aplikacja szablon można użyć (działa na 9.16; nie testowane na 1.x ale powinno działać):

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

Można napisać inne uchwyty samemu :)