2011-12-21 15 views
12

Estoy construyendo un sistema simple como un servicio de noticias en tiempo real, usando node.js + socket.io.node.js + socket.io transmitido desde el servidor, en lugar de desde un cliente específico?

Dado que este es un sistema de "solo lectura", los clientes se conectan y reciben datos, pero los clientes nunca envían ningún dato propio. El servidor genera los mensajes que deben enviarse a todos los clientes, ningún cliente genera ningún mensaje; sin embargo, necesito transmitir.

El documentation for socket.io's broadcast (al final de la página) dice

para transmitir, basta con añadir una bandera broadcast a emit y send llamadas a métodos. La radiodifusión significa enviar un mensaje a todos los demás, excepto el conector que lo inicia.

Así que actualmente capturan el cliente más reciente para conectar, en una variable, entonces emit() a ese socket ybroadcast.emit() a la toma de corriente, de tal manera que este nuevo cliente obtiene los nuevos datos y todos los otros clientes . Pero parece que el rol del cliente aquí no es más que una solución para lo que pensé que socket.io ya soportaba.

¿Hay alguna manera de enviar datos a todos los clientes basándose en un evento iniciado por el servidor?

Mi enfoque actual es más o menos:

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

Básicamente los eventos que causan a los datos requieren el envío al cliente son todos del lado del servidor, no del lado del cliente.

Respuesta

16

¿Por qué no hacer simplemente como a continuación?

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

Cuando lo intenté recibí el error de que 'io.sockets.emit' no es una función definida. – d11wtq

+0

Funciona para mí: P, ¿qué versión de socket io estás usando – user482594

+2

Hmm, parece que en realidad probé 'io.sockets.broadcast.emit()', mi mal, ¡parece que funciona! – d11wtq

4

Dado que está emitiendo eventos solo del lado del servidor, debe crear un EventEmitter personalizado para su servidor.

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 es sólo un ejemplo de eventos, puede tener tantos eventos como desee.

Importante

La solución anterior es mejor también porque en el futuro puede que tenga que emitir ciertos mensajes sólo a algunos clientes, no todas (por lo tanto necesitan condiciones). Para algo más simple (simplemente emita un mensaje a todos los clientes, pase lo que pase), io.sockets.broadcast.emit() es un mejor ajustado de hecho.

+0

Ah, yo estaba haciendo algo muy similar antes, aunque con más de un observador patrón de diseño convencional (es mi primer día usando nodo), pero yo estaba preocupado de que el bucle era ineficiente. Los nuevos mensajes se transmiten cada 7 segundos a alrededor de 10,000 clientes. – d11wtq

+0

Supuse que broadcast usaba un algoritmo eficiente, pero tal vez solo sea una abstracción. Probaré su enfoque;) – d11wtq

+0

Un poco fuera de tema, pero ¿necesito manejar la desconexión, o será que socket.io/node se encargue de ello por mí? Parece que terminaría con observadores de eventos muertos. – d11wtq

Cuestiones relacionadas