2012-03-27 31 views
5

Quali sono gli approcci per il dimensionamento delle applicazioni socket.io? Vedo il seguente problema che non capisco come risolvere:Scaling socket.io tra server

  • Come si può trasmettere un'app socket.io in scala a una stanza? In altre parole, in che modo socket.io conoscerà i vicini di altri server?

È difficile per me immaginare come dovrebbe funzionare, forse un archivio di varianti condiviso per tutte le informazioni necessarie, come i redis, è questa una possibilità?

EDIT: Ho trovato questo articolo: http://www.ranu.com.ar/2011/11/redisstore-and-rooms-with-socketio.html

Sulla base di esso ho fatto la seguente:

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

ma ottengo il seguente errore:

 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) 

mie credenziali Redis sono sicuramente corretta.

MODIFICA: molto strano, ma con autorizzazione Redis disattivata, quindi tutto funziona. Quindi la domanda è ancora valida. Inoltre, ho una domanda su come ottenere informazioni (ad esempio il nome utente) per tutti i partecipanti di un gruppo (stanza) in questa modalità RedisStorage, è possibile implementarlo? Idealmente questo può essere fatto attraverso la funzionalità Redis Pub/Sub.

risposta

0

Prova ad aggiungere questo codice in;

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

Non lo risolverà, ma dovrebbe fornire almeno un errore più utile.

0

Ti ho suggerito di non utilizzare RedisStore. Ha un problema con l'utilizzo della CPU a causa del suo scarso utilizzo di pub-sub che risultano inovabili (può ricevere meno di un'istanza di node.js pura con socket.io che è piuttosto inutile). Personalmente ho usato Redis come archivio dati per mantenere la lista delle stanze e implementare la mia funzione di stanza (Redis è un database di valori-chiave in memoria ma ha una meccanica persistente). Quando si desidera un dato stanza, è sufficiente recuperare i dati dagli stessi redis e il gioco è fatto. Tuttavia, per poter eseguire Socket.io in più istanze, è necessario anche un servizio di bilanciamento del carico come HAProxy, Nginx per separare i lavori su più porte node.js, altrimenti l'utente utilizzerà comunque solo un processo node.js. Questo è un lavoro enorme. Se si ha anche altri frontend web in altra lingua, che è più lavoro anche perché un po 'di blocco della rete tutte le porte tranne la porta 80 e 443. Puoi leggere ulteriori informazioni su queste cose:

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

0

Un'altra possibile soluzione è utilizzare un'alternativa come PubNub per ridimensionare l'interazione in tempo reale. Mi sono imbattuto in un problema simile nello sviluppo di Mote.io e ho deciso di utilizzare una soluzione ospitata invece di creare un servizio di bilanciamento del carico. Ora lavoro per PubNub.

PubNub si prenderà cura del problema di datasync di cui si sta parlando. Normalmente è necessario sincronizzare i redis tra i server o bilanciare il carico dei client sulla stessa istanza per assicurarsi che ricevano tutti gli stessi messaggi. PubNub riassume questo in modo da non doverlo preoccupare.

applicazioni chat in tempo reale in 10 righe di codice

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>