The Right Code

Home of Greg Bergé. Let's speak about JavaScript.

Use primus with a cluster

What is Primus ?

Primus is a great module, it provides an abstraction for real-time library. You can use Engine.IO, ws or SockJS without changing any line of code. But that's not the only advantage of Primus. The library has a lot of plugins: events, rooms or resources (share code with client).

So Primus is cool, but out of box it doesn't scale on a node cluster or on multiple servers... Fortunately, there is a plugin to do that!

Use primus with node cluster

Start with creating a basic node cluster with 20 workers:

var cluster = require('cluster');  
var http = require('http');

if (cluster.isMaster) {  
  // Fork workers.
  for (var i = 0; i < 20; i++) {
    cluster.fork();
  }

  return ;
}

var server = http.createServer().listen(8000);  

Now we must attached Primus to the server, don't forget to install it with npm install primus.

var Primus = require('primus');  
var primus = new Primus(server);  

Now we will create a small application with two routes:

server.on('request', function handler(req, res) {

  // Connect to primus and show an alert if a "hello" message is received.
  if (req.url === '/') {
    res.end('\
      <script src="/primus/primus.js"></script>\
      <script>\
      var primus = new Primus();\
      primus.on("data", function (data) {\
        if (data === "hello") alert("hello");\
      });\
      </script>\
    ');
  }

  // Broadcast an "hello" message.
  if (req.url === '/broadcast') {
    primus.write('hello');
    res.end('broadcasted');
  }

  res.statusCode = 404;
  res.end();
});

As now, if you start your webserver and you start using Primus you will observe some strange thing. All clients will not receive the message.

The message is broadcasted only to the clients connected to this worker. So if you have 20 workers, 100 clients, you will broadcast about 5 clients.

To reach all clients, we must add a bus between all clients. It's exactly what the plugin primus-cluster provides. It uses redis and its Pub/Sub feature to connect the clients to each others.

So let's use this module in our small application.

var PrimusCluster = require('primus-cluster');  
primus.use('cluster', PrimusCluster);  

If you start the application, you will an error will be displayed in console.

You must add redis as dependency  

primus-cluster doesn't include the redis module to let you choose the version of your choice. So you must install redis npm install redis.

If you restart the application, all clients will receive the message and you will see as many alerts as connected clients.

You can now use Primus in your application and scale it, the next WhatsApp awaits you!

Full gist

comments powered by Disqus