2012-03-27 30 views
5

¿Cuáles son los enfoques para escalar aplicaciones socket.io? Veo el siguiente problema que no entiendo cómo resolver:Escalado socket.io entre servidores

  • ¿Cómo se puede transmitir una aplicación socket.io escalada a una habitación? En otras palabras, ¿cómo sabrá socket.io sobre los vecinos de otros servidores?

Me resulta difícil imaginar cómo debería funcionar, tal vez una tienda de variante compartida para toda la información necesaria, como redis, ¿es esta una posibilidad?

EDIT: He encontrado este artículo: http://www.ranu.com.ar/2011/11/redisstore-and-rooms-with-socketio.html

Sobre la base de lo que hice lo siguiente:

var pub = redis.createClient(); 
    var sub = redis.createClient(); 
    var store = redis.createClient(); 
    pub.auth("pass"); 
    sub.auth("pass"); 
    store.auth("pass"); 

    io.configure(function(){ 
io.enable('browser client minification'); // send minified client 
io.enable('browser client etag');   // apply etag caching logic based on version number 
    io.enable('browser client gzip');   // gzip the file 
io.set('log level', 1);     // reduce logging 
io.set('transports', [      // enable all transports (optional if you want flashsocket) 
    'websocket' 
    , 'flashsocket' 
    , 'htmlfile' 
    , 'xhr-polling' 
    , 'jsonp-polling' 
]); 
var RedisStore = require('socket.io/lib/stores/redis'); 
io.set('store', new RedisStore({redisPub:pub, redisSub:sub, redisClient:store})); 
    }); 

pero me da el siguiente error:

 Error: Uncaught, unspecified 'error' event. 
    at RedisClient.emit (events.js:50:15) 
    at Command.callback (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:232:29) 
    at RedisClient.return_error (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:382:25) 
    at RedisReplyParser.<anonymous> (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:78:14) 
    at RedisReplyParser.emit (events.js:67:17) 
    at RedisReplyParser.send_error ( /home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js:265:14) 
    at RedisReplyParser.execute (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js:124:22) 
    at RedisClient.on_data (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:358:27) 
    at Socket.<anonymous> (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:93:14) 
    at Socket.emit (events.js:67:17) 

Mis credenciales Redis son definitivamente correcto.

EDITAR: Muy extraño, pero con la autorización de Redis desactivada, entonces todo funciona. Entonces la pregunta aún es válida. Además, tengo una pregunta sobre cómo obtener información (por ejemplo, nombre de usuario) para todos los participantes de un grupo (sala) en este modo RedisStorage, ¿es posible implementar esto? Idealmente, esto se puede hacer a través de la funcionalidad Redis Pub/Sub.

Respuesta

0

Trate de añadir este código en;

pub.on('error', function (err) { 
    console.error('pub', err.stack); 
}); 
sub.on('error', function (err) { 
    console.error('sub', err.stack); 
}); 
store.on('error', function (err) { 
    console.error('store', err.stack); 
}); 

No lo arreglará, pero al menos debería darle un error más útil.

0

Le sugerí que no utilice RedisStore. Tiene un problema con el uso de la CPU debido a su uso de pub-sub que no se puede escalar (puede recibir menos de una instancia de node.js puro con socket.io, lo cual es bastante inútil). Personalmente utilicé Redis como una tienda de datos para mantener la lista de salas allí e implementar mi propia función de sala (Redis es una base de datos clave-valor en la memoria pero tiene una mecánica persistente). Cuando desee una información de habitación, solo busque datos de la misma redis y listo. Sin embargo, para poder ejecutar Socket.io en varias instancias, también necesita un equilibrador de carga como HAProxy, Nginx para separar trabajos en múltiples puertos node.js o, de lo contrario, su usuario seguirá utilizando solo un proceso node.js. Este es un gran trabajo. Si también tiene otra interfaz web en otro idioma, que es más trabajo también porque algunos bloques de la red todos los puertos excepto el puerto 80 y 443. Se puede leer más información acerca de estas cosas en:

http://book.mixu.net/node/ch13.html

0

Otra posible solución es utilizar una alternativa como PubNub para escalar la interacción en tiempo real. Encontré un problema similar al desarrollar Mote.io y decidí ir con una solución alojada en lugar de crear un equilibrador de carga. Ahora trabajo para PubNub.

PubNub se ocupará del problema de datasync del que está hablando. Normalmente, necesitaría sincronizar los redis en los servidores o equilibrar la carga de sus clientes en la misma instancia para asegurarse de que reciban todos los mismos mensajes. PubNub abstrae esto para que no tenga que preocuparse por eso.

en tiempo real Aplicaciones de Chat en 10 líneas de código

enter image description here

Enter Chat and press enter 
<div><input id=input placeholder=you-chat-here /></div> 

Chat Output 
<div id=box></div> 

<script src=http://cdn.pubnub.com/pubnub.min.js></script> 
<script>(function(){ 
var box = PUBNUB.$('box'), input = PUBNUB.$('input'), channel = 'chat'; 
PUBNUB.subscribe({ 
    channel : channel, 
    callback : function(text) { box.innerHTML = (''+text).replace(/[<>]/g, '') + '<br>' + box.innerHTML } 
}); 
PUBNUB.bind('keyup', input, function(e) { 
    (e.keyCode || e.charCode) === 13 && PUBNUB.publish({ 
     channel : channel, message : input.value, x : (input.value='') 
    }) 
}) 
})()</script> 
Cuestiones relacionadas