2012-03-27 8 views
5

Was sind die Ansätze zum Skalieren von socket.io-Anwendungen? Ich sehe das folgende Problem, das ich nicht verstehe, wie lösen:Scaling socket.io zwischen Servern

  • Wie kann eine skalierte socket.io App in ein Zimmer übertragen? Mit anderen Worten, wie wird socket.io über die Nachbarn von anderen Servern wissen?
  • Es ist schwer für mich vorzustellen, wie es funktionieren sollte - vielleicht eine gemeinsame Variante speichern für alle notwendigen Informationen, wie zum Beispiel - ist das eine Möglichkeit?

    EDIT: Ich fand diesen Artikel: http://www.ranu.com.ar/2011/11/redisstore-and-rooms-with-socketio.html

    darauf basierenden ich folgendes getan:

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

    Aber ich folgende Fehlermeldung erhalten:

     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) 
    

    definitiv Meine Redis Zugangsdaten sind richtig.

    EDIT: Sehr seltsam, aber mit Redis Autorisierung deaktiviert dann funktioniert alles. Die Frage ist also immer noch gültig. Außerdem habe ich eine Frage, wie man Informationen (zum Beispiel Benutzername) für alle Teilnehmer einer Gruppe (Raum) in diesem RedisStorage-Modus bekommt, ist das möglich? Idealerweise kann dies über die Redis Pub/Sub-Funktionalität erfolgen.

    Antwort

    0

    Versuchen das Hinzufügen dieser Code in arbeiten;

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

    Es wird es nicht beheben, aber es sollte Ihnen zumindest einen nützlicheren Fehler geben.

    0

    Ich schlug vor, dass Sie RedisStore nicht verwenden. Es hat ein Problem mit der CPU-Nutzung wegen seiner schlechten Verwendung von Pub-Sub, die in unskalierbar (Es kann laden weniger als eine reine node.js-Instanz mit socket.io, was ziemlich nutzlos ist). Ich persönlich habe Redis als Datenspeicher benutzt, um die Raumliste dort zu behalten und meine eigene Raumfunktion zu implementieren (Redis ist eine Schlüssel-Wert-Datenbank im Speicher, hat aber persistente Mechanik). Wenn Sie ein Zimmerdaten wollen, holen Sie einfach Daten von demselben redis und das ist es. Um Socket.io jedoch mehrfach ausführen zu können, benötigen Sie außerdem einen Load-Balancer wie HAProxy, Nginx, um Arbeiten an mehrere node.js-Ports zu trennen, oder Ihr Benutzer wird weiterhin nur einen node.js-Prozess verwenden. Das ist eine große Arbeit. Wenn Sie auch andere Web-Frontend in einer anderen Sprache hat, ist, dass mehr Arbeit zu, weil einige Netzwerkblock alle Port außer Port 80 und 443. Sie an mehr Informationen über diese Dinge lesen:

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

    0

    Eine andere mögliche Lösung ist eine Alternative wie PubNub zu verwenden, um Echtzeitinteraktion zu skalieren. Bei der Entwicklung von Mote.io stieß ich auf ein ähnliches Problem und entschied mich für eine gehostete Lösung anstelle eines Load Balancers. Ich arbeite jetzt für PubNub.

    PubNub wird sich um das Datensynchproblem kümmern, von dem Sie sprechen. Normalerweise müssten Sie redis über mehrere Server hinweg synchronisieren oder Ihre Clients auf dieselbe Instanz ausgleichen, um sicherzustellen, dass sie alle die gleichen Nachrichten erhalten. PubNub abstrahiert dies, so dass Sie sich keine Sorgen machen müssen.

    Echtzeit-Chat Apps in 10 Lines of Code

    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>