SocketCluster
SocketCluster is a WebSocket server cluster (with HTTP long-polling fallback) based on engine.io.
Unlike other realtime engines, SocketCluster deploys itself as cluster in order to make use of all CPUs/cores on
a machine/instance - This offers a more consistent performance for users and lets you scale vertically without limits.
SocketCluster workers are highly parallelized - Asymptotically speaking, SocketCluster is N times faster than any other
available WebSocket server (where N is the number of CPUs/cores available on your machine).
SocketCluster was designed to be lightweight and its API is almost identical to Socket.io.
Other advantages of SocketCluster include:
- Sockets which are bound to the same browser (for example, across multiple tabs) share the same session.
- You can emit an event on a session to notify all sockets that belong to it.
- The SocketCluster client (socketcluster-client) has an option to allow disconnected sockets to automatically (and seamlessly) reconnect
if they lose the connection.
- Server crashes are transparent to users (aside from a 2 to 5 second delay to allow the worker to respawn) - Session data remains intact between crashes.
- It uses a memory store cluster called nData which you can use to store 'volatile' session data which relates to your sockets/sessions.
To install, run:
npm install socketcluster
Note that to use socketcluster you will also need the client which you an get using the following command:
npm install socketcluster-client
The socketcluster-client script is called socketcluster.js (located in the main socketcluster-client directory)
How to use
The following example launches SocketCluster as 7 distinct processes (in addition to the current master process):
- 3 workers on ports 9100, 9101, 9102
- 3 stores on ports 9001, 9002, 9003
- 1 load balancer on port 8000 which distributes requests evenly between the 3 workers
var socketCluster = new SocketCluster({
workers: [9100, 9101, 9102],
stores: [9001, 9002, 9003],
balancerCount: 1,
port: 8000,
appName: 'myapp',
workerController: 'worker.js'
});
The appName option can be any string which uniquely identifies this application.
This avoids potential issues with having multiple SocketCluster apps run under the same domain
- It is used internally for various purposes.
The workerController option is the path to a file which each SocketCluster worker will use to bootstrap itself.
This file is a standard Node.js module which must expose a run() function - Inside this run function is where you should
put all your application logic.
Example 'worker.js':
var fs = require('fs');
module.exports.run = function (worker) {
var httpServer = worker.getHTTPServer();
var wsServer = worker.getWSServer();
var htmlPath = __dirname + '/index.html';
var clientPath = __dirname + '/node_modules/socketcluster-client/socketcluster.js';
var html = fs.readFileSync(htmlPath, {
encoding: 'utf8'
});
var clientCode = fs.readFileSync(clientPath, {
encoding: 'utf8'
});
httpServer.on('req', function (req, res) {
if (req.url == '/socketcluster.js') {
res.writeHead(200, {
'Content-Type': 'text/javascript'
});
res.end(clientCode);
} else if (req.url == '/') {
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.end(html);
}
});
wsServer.on('connection', function (socket) {
setInterval(function () {
socket.emit('rand', Math.floor(Math.random() * 100));
}, 1000);
});
};
Using with Express
Using SocketCluster with express is simple, you put the code inside your workerController:
module.exports.run = function (worker) {
var httpServer = worker.getHTTPServer();
var wsServer = worker.getWSServer();
var app = require('express')();
httpServer.on('req', app);
}
API (Documentation coming soon)
SocketCluster
Exposed by require('socketcluster').SocketCluster
.
SocketCluster(opts:Object)
Creates a new SocketCluster, must be invoked with the new keyword.
var SocketCluster = require('socketcluster').SocketCluster;
var socketCluster = new SocketCluster({
workers: [9100, 9101, 9102],
stores: [9001, 9002, 9003],
port: 8000,
appName: 'myapp',
workerController: 'worker.js'
});
Documentation on all supported options is coming soon (there are around 30 of them - Most of them are optional).
SocketWorker
A SocketWorker object is passed as the argument to your workerController's run(worker) function.
Example - Inside worker.js:
module.exports.run = function (worker) {
}
ClusterServer
A ClusterServer instance is returned from worker.getWSServer() - You use it to handle WebSocket connections.