2014-10-15 10 views
5

Ich habe ein Problem mit dem Clustering meiner Anwendung mit Node.js, socket.io und node.js-Cluster.WebSocket-Handshake in Node.JS, Socket.IO und Clustern funktioniert nicht

Ich benutze die socket.io-redisis, um die Informationen für alle Arbeiter zu teilen, aber funktioniert nicht.

Mein Code:

var cluster = require('cluster'); 
var numCPUs = require('os').cpus().length; 

if (cluster.isMaster) { 
    // Fork workers. 
    for (var i = 0; i < numCPUs; i++) {  
    cluster.fork(); 
    } 

    cluster.on('exit', function(worker, code, signal) { 
    console.log('worker ' + worker.process.pid + ' died'); 
    }); 
} else { 

    ... 

     var express = require("express"); 
     //Server 
     var server = express(); 
     //Socket.io 
     var http = require('http').Server(server); 
     var io = require('socket.io')(http); 
     var redis_io = require('socket.io-redis'); 
     var redis = require("redis"); 

     io.adapter(redis_io({host: "127.0.0.1", port: 6379 })); 

    ... 
} 

Im Client, bekomme ich Fehler in Handshake wie 400-Fehler oder WebSocket geschlossen wird, bevor die Verbindung hergestellt ist.

Was kann ich tun, um das zu lösen?

Im die letzte Version von node.js und Socket.io

Dank mit!

Antwort

15

Ich hatte das gleiche Problem und es dauerte eine Weile, um es herauszufinden. Ein wenig Forschung hat erklärt, dass es daran liegt, dass einige der Transporte, wie Long-Polling, mehrere Anfragen stellen müssen, um die optimale Verbindung herzustellen. Es gibt einen Zustand, der zwischen Anforderungen gehalten wird. Wenn also verschiedene aufeinander folgende Anforderungen an verschiedene Cluster-Worker weitergeleitet werden, schlägt die Verbindung fehl.

Es ist eine Seite über die es bei http://socket.io/docs/using-multiple-nodes/, der ein eigenes cluster Modul sticky-session genannt zitiert, die sich um das funktioniert: https://github.com/indutny/sticky-session

Ich wollte wirklich nicht, es zu benutzen, da diese im Grunde die ganze Arbeit ignoriert die node.js Team hat in den TCP-Lastausgleich hinter dem Cluster-Modul investiert.

Da das Web Socket-Protokoll selbst nur eine einzige Verbindung benötigt, konnte ich dies umgehen, indem ich websocket gezwungen habe, der erste und einzige Transport zu sein. Ich kann dies tun, weil ich den Client und den Server kontrolliere. Für eine öffentliche Webseite ist dies möglicherweise nicht sicher, da Sie sich um die Browserkompatibilität kümmern müssen. In meinem Fall ist der Client eine mobile App.

Hier wird der JavaScript-Client-Code ist ich in meiner Testseite setzen (wieder ist der eigentliche Client eine mobile App, also hier meine Web-Seite wirklich nur ein Hilfsmittel zu bauen und testen helfen):

var socket = io('http://localhost:8080/', { 
    transports: [ 'websocket' ] 
}); 
+0

Brandon, danke !!! Ihre Lösung ist das Beste! –

Verwandte Themen