Does anybody know a good solution to scale a node.js - socket.io based app up over multiple cores? I am currently testing the solution presented in the socket.io documentation, to use socket.io over multiple nodes, but without a concrete success.
I have created a playground for this on github: https://github.com/liviuignat/socket.io-clusters which is a bit modified copy of the chat application from the socket.io site. It uses express, cluster, [email protected] and socket.io-redis.
There is currently also an implementation using sticky-session in the branch feature/sticky which seems to work better.
In the end the application needs to be published to Heroku, scaled over multiple dynos.
Initially I tryied doing something like this - to start the server only for the cluster nodes, but I always get the error: failed: Connection closed before receiving a handshake response
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();
}
Then I tried starting the server also for master nodes:
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();
}
I also tried it using both sticky-session and socket.io-redis in the branch feature/sticky, which seems to perform with success, but still does not seems to be a good solution:
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');
});
}
I will do more tests for the next days, but, it would help a lot if anybody could come up with some ideas.
Thanks,