2011-12-21 1 views
12

Buduję prosty system, taki jak kanał informacyjny w czasie rzeczywistym, używając node.js + socket.io.node.js + socket.io jest transmitowane z serwera, a nie z konkretnego klienta?

Ponieważ jest to system "tylko do odczytu", klienci łączą się i odbierają dane, ale klienci nigdy nie wysyłają żadnych własnych danych. Serwer generuje komunikaty, które należy wysłać do wszystkich klientów, żaden klient nie generuje żadnych komunikatów; ale muszę nadawać.

documentation for socket.io's broadcast (koniec strony) mówi

Aby nadawać, wystarczy dodać broadcast flagę emit i send wywołań metod. Nadawanie oznacza wysyłanie wiadomości do wszystkich osób poza gniazdem, które je uruchamia.

więc obecnie uchwycić najnowszego klienta, aby połączyć, do zmiennej, a następnie emit() do tego gniazda ibroadcast.emit() do tego gniazda, tak że ten nowy klient dostaje nowe dane i wszystkich innych klientów . Ale wygląda na to, że rola klienta tutaj jest niczym więcej niż obejściem tego, co uważałem już za obsługiwane przez socket.io.

Czy istnieje sposób przesyłania danych do wszystkich klientów na podstawie zdarzenia zainicjowanego przez serwer?

Moje obecne podejście jest grubsza:

var socket; 

io.sockets.on("connection", function (s) { 
    socket = s; 
}); 

/* bunch of real logic, yadda yadda ... */ 

myServerSideNewsFeed.onNewEntry(function (msg) { 
    socket.emit("msg", { "msg" : msg }); 
    socket.broadcast.emit("msg", { "msg" : msg }); 
}); 

Zasadniczo zdarzenia, które powodują dane wymagają wysyłania do klienta są po stronie serwera, a nie po stronie klienta.

Odpowiedz

16

Dlaczego po prostu nie lubię poniżej?

io.sockets.emit('hello',{msg:'abc'}); 
+0

Kiedy spróbowałem, dostałem błąd, że 'io.sockets.emit' nie jest zdefiniowaną funkcją. – d11wtq

+0

To działa dla mnie: P, jaka wersja gniazda io używasz – user482594

+2

Hmm, wydaje się, że faktycznie wypróbowałem 'io.sockets.broadcast.emit()', moje złe, to wydaje się działać! – d11wtq

4

Ponieważ emitujesz zdarzenia tylko po stronie serwera, powinieneś utworzyć niestandardowy EventEmitter dla swojego serwera.

var io = require('socket.io').listen(80); 
    events = require('events'), 
    serverEmitter = new events.EventEmitter(); 

io.sockets.on('connection', function (socket) { 
    // here you handle what happens on the 'newFeed' event 
    // which will be triggered by the server later on 
    serverEmitter.on('newFeed', function (data) { 
    // this message will be sent to all connected users 
    socket.emit(data); 
    }); 
}); 

// sometime in the future the server will emit one or more newFeed events 
serverEmitter.emit('newFeed', data); 

Uwaga: newFeed to tylko przykład zdarzenie, można mieć wiele imprez, jak chcesz.

Ważne

powyżej rozwiązanie jest lepsze, ponieważ również w przyszłości może trzeba wydzielać pewne wiadomości tylko do niektórych klientów, nie wszystko (stąd potrzeba warunki). Dla czegoś prostszego (po prostu wyślij wiadomość do wszystkich klientów bez względu na wszystko), jest w istocie lepszym rozwiązaniem.

+0

Ach, robiłem coś bardzo podobnego wcześniej, choć z bardziej konwencjonalnego wzorca projektowego obserwator (to mój pierwszy dzień za pomocą węzła), ale był zaniepokojony, że pętla był nieskuteczny. Nowe wiadomości są wysyłane co 7 sekund do około 10 000 klientów. – d11wtq

+0

Założono, że nadawanie używało skutecznego algorytmu, ale może to tylko abstrakcja. Spróbuję Twojego podejścia;) – d11wtq

+0

Trochę nie na temat, ale czy muszę obsługiwać rozłączenie, czy też socket.io/node zajmie się tym dla mnie? Wygląda na to, że skończę z martwymi obserwatorami zdarzeń. – d11wtq