2011-12-21 1 views
12

Sto costruendo un sistema semplice come un news feed in tempo reale, usando node.js + socket.io.node.js + socket.io trasmesso dal server, piuttosto che da un client specifico?

Poiché questo è un sistema di "sola lettura", i client si connettono e ricevono i dati, ma i client non inviano mai dati personali. Il server genera i messaggi che devono essere inviati a tutti i client, nessun client genera alcun messaggio; ma ho bisogno di trasmettere.

Il documentation for socket.io's broadcast (fine della pagina) dice

per trasmettere, è sufficiente aggiungere un flag broadcast per emit e send chiamate di metodo. Trasmissione significa inviare un messaggio a tutti tranne che al socket che lo avvia.

Così ho attualmente catturare il cliente più recente per la connessione, in una variabile, quindi emit() a quella presa ebroadcast.emit() a quella presa, in modo tale che questo nuovo client ottiene i nuovi dati e tutti gli altri clienti . Ma sembra che il ruolo del cliente qui non sia altro che una soluzione per ciò che pensavo che socket.io già supportasse.

C'è un modo per inviare dati a tutti i client in base a un evento avviato dal server?

Il mio approccio attuale è più o meno:

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

Fondamentalmente gli eventi che causano i dati di richiedere l'invio al cliente sono tutti sul lato server, non sul lato client.

risposta

16

Perché non fare come sotto?

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

Quando ho provato ho ricevuto un errore che 'io.sockets.emit' non è una funzione definita. – d11wtq

+0

Funziona per me: P, quale versione di socket io stai utilizzando – user482594

+2

Hmm, sembra che io abbia effettivamente provato 'io.sockets.broadcast.emit()', il mio male, sembra funzionare! – d11wtq

4

Poiché si stanno emettendo eventi solo lato server, è necessario creare un numero personalizzato EventEmitter per il proprio server.

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); 

Nota: newFeed è solo un esempio evento, si può avere il maggior numero di eventi che vuoi.

Importante

La soluzione di cui sopra è meglio anche perché in futuro potrebbe essere necessario emettere determinati messaggi solo per alcuni clienti, non tutti (e quindi hanno bisogno di condizioni). Per qualcosa di più semplice (basta emettere un messaggio a tutti i client, non importa quale), io.sockets.broadcast.emit() è un meglio adattato allo.

+0

Ah, mi stava facendo qualcosa di molto simile prima, anche se con più di un modello di progettazione osservatore convenzionale (è il mio primo giorno con nodo), ma era preoccupato che il ciclo era inefficiente. I nuovi messaggi vengono trasmessi ogni 7 secondi a circa 10.000 clienti. – d11wtq

+0

Ho pensato che la trasmissione usasse un algoritmo efficiente, ma forse è solo un'astrazione. Proverò il tuo approccio;) – d11wtq

+0

Un po 'fuori tema, ma ho bisogno di gestire la disconnessione, o socket.io/node si prenderà cura di esso per me? Sembra che finirei con osservatori di eventi morti. – d11wtq