La autorización de Socket.io websocket falla al agrupar la aplicación del nodo

Pregunta: ¿Es posible agrupar una aplicación que utiliza Socket.io para el soporte de WebSocket? Si es así, ¿cuál sería el mejor método de implementación?

Construí una aplicación que usa Express y Socket.io, construida en Node.js. Me gustaría incorporar la agrupación en clústeres para boost la cantidad de solicitudes que puede procesar mi aplicación.

Lo siguiente hace que mi aplicación genere un error de reconocimiento de 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 registro de la consola muestra que socket.io se está iniciando varias veces.

 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 se está configurando actualmente en la parte superior de mi código de servidor usando:

 var io = require('socket.io').listen(app); 

El código de autorización 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); } }); 

Registro de consola del mensaje de error:

 Error whilst authorizing websocket handshake debug - authorized warn - handshake error Error 

¿Cuál es tu sessionStore ? Si es el MemoryStore incluye con connect , las sesiones no se compartirán entre sus trabajadores. Cada trabajador tendrá su propio conjunto de sesiones, y si un cliente se conecta con otro trabajador, no encontrará su sesión. Le sugiero que eche un vistazo a, por ejemplo, connect-redis para compartir sesiones entre procesos. Uso básico:

 var connect = require('connect') , RedisStore = require('connect-redis')(connect); var app = connect.createServer(); app.use(connect.session({store: new RedisStore, secret: 'top secret'}); 

Por supuesto, esto requiere que también configures redis. En la wiki de Connect hay módulos para CouchDB, memcached, postgres y otros.

Sin embargo, esto solo resuelve parte de su problema, porque ahora tiene sesiones compartidas entre trabajadores, pero socket.io no tiene forma de enviar mensajes a clientes que están conectados a otros trabajadores. Básicamente, si emite un socket.emit en un trabajador, ese mensaje solo se enviará a los clientes conectados a ese mismo trabajador. Una solución para esto es usar RedisStore para socket.io , que aprovecha redis para enrutar mensajes entre trabajadores. Uso básico:

 var sio = require('socket.io') , RedisStore = sio.RedisStore , io = sio.listen(app); io.set('store', new RedisStore); 

Ahora, todos los mensajes deben ser enrutados a los clientes sin importar a qué trabajadores estén conectados.

Vea también: Node.js, multi-threading y Socket.io

    Intereting Posts