socket rooms room node example all node.js heroku redis socket.io scale

rooms - Escala node.js socket.io@1.*.* con cluster y socket.io-redis en Heroku



socket io socket io js (1)

Probablemente estés buscando socket.io-redis. http://socket.io/blog/introducing-socket-io-1-0/ (vaya a ''Escalabilidad'')

Aquí hay un ejemplo abreviado sobre cómo crear el andamio con socket.io + express:

var cluster = require(''cluster''); var express = require(''express'') , app = express() , server = require(''http'').createServer(app); var io = require(''socket.io'').listen(server) var redis = require(''socket.io-redis''); io.adapter(redis({ host: ''localhost'', port: 6379 })); var workers = process.env.WORKERS || require(''os'').cpus().length; /** * Start cluster. */ if (cluster.isMaster) { /** * Fork process. */ console.log(''start cluster with %s workers'', workers-1); workers--; for (var i = 0; i < workers; ++i) { var worker = cluster.fork(); console.log(''worker %s started.'', worker.process.pid); } /** * Restart process. */ cluster.on(''death'', function(worker) { console.log(''worker %s died. restart...'', worker.process.pid); cluster.fork(); }); } else { server.listen(process.env.PORT || 9010); }

Redis tiene pub / sub y todos los nodos socket.io necesitan suscribirse a redis para obtener todos los mensajes de un canal. De esta forma, un proceso puede transmitir un mensaje a un canal (publicar) y todos los demás procesos reciben los mensajes con una latencia mínima para transmitirlos a sus clientes conectados (suscribirse). Incluso puede extender esto con sesiones basadas en redis.

El módulo de clúster al que se refiere es un poco engañoso en mi opinión. Ayuda a crear subprocesos individuales en la medida en que entiendo el concepto, pero no "sincroniza" los canales en múltiples nodos. Si sus clientes no necesitan comunicarse con otros, está bien. Si desea transmitir mensajes a todos los clientes conectados en todos los nodos, necesita el módulo redis.

¿Alguien conoce una buena solución para escalar una aplicación basada en node.js - socket.io en múltiples núcleos? Actualmente estoy probando la solución presentada en la documentación de socket.io, para usar socket.io en varios nodos, pero sin un éxito concreto.

He creado un patio de recreo para esto en github: https://github.com/liviuignat/socket.io-clusters, que es una copia modificada de la aplicación de chat del sitio socket.io. Utiliza express , cluster , [email protected] y socket.io-redis .

Actualmente también hay una implementación que usa sticky-session en la feature/sticky rama feature/sticky que parece funcionar mejor.

Al final, la aplicación debe publicarse en Heroku , a escala en múltiples dynos.

Inicialmente intenté hacer algo como esto: iniciar el servidor solo para los nodos del clúster, pero siempre obtengo el error: error : conexión cerrada antes de recibir una respuesta de saludo.

if (cluster.isMaster) { 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 server = new Server({ dirName: __dirname, enableSocket: true }) .setupApp() .setupRoutes() .start(); }

Luego intenté iniciar el servidor también para nodos maestros:

if (cluster.isMaster) { var server = new Server({ dirName: __dirname, enableSocket: true }) .setupApp() .setupRoutes() .start(); 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 server = new Server({ dirName: __dirname, enableSocket: true }) .setupApp() .setupRoutes() .start(); }

También lo intenté utilizando tanto sticky-session como socket.io-redis en la feature/sticky rama feature/sticky , que parece funcionar con éxito, pero aún así no parece ser una buena solución:

if (cluster.isMaster) { sticky(function() { var server = new Server({ dirName: __dirname, enableSocket: true }) .setupApp() .setupRoutes(); return server.http; }).listen(3000, function() { console.log(''server started on 3000 port''); }); for (var i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on(''exit'', function(worker, code, signal) { console.log(''worker '' + worker.process.pid + '' died''); }); } else { sticky(function() { var server = new Server({ dirName: __dirname, enableSocket: true }) .setupApp() .setupRoutes(); return server.http; }).listen(3000, function() { console.log(''server started on 3000 port''); }); }

Haré más pruebas para los próximos días, pero sería de gran ayuda si alguien pudiera aportar algunas ideas.

Gracias,