J'ai construit une application qui utilise Express et Socket.io, construit sur Node.js. J'aimerais intégrer le clustering pour augmenter le nombre de demandes que mon application peut traiter.
Ce qui suit provoque mon application pour produire une erreur de prise de contact socket …
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('death', function(worker) { console.log('worker ' + worker.pid + ' died'); }); } else { app.listen(3000); }
Un journal de console montre que socket.io est lancé à plusieurs reprises.
jack@jack:~$ node nimble/app.js info - socket.io started info - socket.io started info - socket.io started info - socket.io started info - socket.io started info - socket.io started info - socket.io started info - socket.io started info - socket.io started
Socket.io est en cours de configuration en haut de mon code de serveur en utilisant:
var io = require('socket.io').listen(app);
Le code d'autorisation du websocket:
//Auth the user io.set('authorization', function (data, accept) { // check if there's a cookie header if (data.headers.cookie) { data.cookie = parseCookie(data.headers.cookie); data.sessionID = data.cookie['express.sid']; //Save the session store to the data object data.sessionStore = sessionStore; sessionStore.get(data.sessionID, function(err, session){ if(err) throw err; if(!session) { console.error("Error whilst authorizing websocket handshake"); accept('Error', false); } else { console.log("AUTH USERNAME: " + session.username); if(session.username){ data.session = new Session(data, session); accept(null, true); }else { accept('Invalid User', false); } } }) } else { console.error("No cookie was found whilst authorizing websocket handshake"); return accept('No cookie transmitted.', false); } });
Journal de la console du message d'erreur:
Error whilst authorizing websocket handshake debug - authorized warn - handshake error Error
Quel est votre sessionStore
? Si c'est le MemoryStore
livré avec connect
, les sessions ne seront pas partagées entre vos travailleurs. Chaque travailleur aura son propre ensemble de sessions, et si un client se connecte à un autre travailleur, vous ne trouverez pas sa session. Je vous suggère de jeter un coup d'oeil, par exemple, connect-redis pour partager des sessions entre les processus. Utilisation de base:
var connect = require('connect') , RedisStore = require('connect-redis')(connect); var app = connect.createServer(); app.use(connect.session({store: new RedisStore, secret: 'top secret'});
Bien sûr, cela exige que vous configurez également des redis. Sur le wiki Connect, il existe des modules pour CouchDB, memcached, postgres et autres.
Cela résout seulement une partie de votre problème, car maintenant vous avez des sessions partagées entre les travailleurs, mais socket.io
n'a aucun moyen d'envoyer des messages aux clients qui sont connectés à d'autres travailleurs. Fondamentalement, si vous socket.emit
un socket.emit
dans un travailleur, ce message ne sera envoyé qu'aux clients connectés à ce même travailleur. Une solution à cela est d'utiliser RedisStore
pour socket.io
, qui exploite redis pour acheminer les messages entre les travailleurs. Utilisation de base:
var sio = require('socket.io') , RedisStore = sio.RedisStore , io = sio.listen(app); io.set('store', new RedisStore);
Maintenant, tous les messages doivent être acheminés vers les clients quel que soit le travailleur auquel ils sont connectés.
Voir aussi: Node.js, multi-threading et Socket.io