Build first, decide later

Introducing, Primus a real-time server abstraction.

Arnout Kazemier
The build
4 min readJul 5, 2013

--

You’re about to build your first real-time application and are excited about it. You start researching the different kind of open source frameworks that should make it a breeze for you, but you’re overwhelmed by the possibilities.

Should you choose SockJS, Engine.IO or maybe just use pure WebSockets. It’s a hard decision to make as you know you’ll be locked in with that framework as you’re building your application on top of that API. But do you really need to be locked in?

The biggest problems always happen when you deploy your application to production servers. This is when they receive large quantities of traffic and small bugs can lead to major disasters. Wouldn’t it be nice to be able to switch between real-time servers when they are the source of your issues without having to rewrite your application?

Primus, the creator god from the Transformers series.

Those were some of the reasons why I’ve built Primus. It’s a lightweight wrapper around various real-time frameworks and provides you with one single, low level and stream compatible interface for both the server and the client.

Primus currently supports:

Engine.IO, Socket.IO, WebSockets, Browserchannel and SockJS.

Getting started with Primus

Primus doesn’t have any dependencies on real-time frameworks, keeping it as lightweight as possible. It doesn’t help anyone if we bundled all 5 frameworks. So this does mean that there are 2 modules you need to install, primus and the framework you want to try out first. In this example we’re just going to build a pure WebSocket based application so we need to install primus and ws:

npm install primus
npm install ws

Once these modules are installed we can start building our application. Primus needs to be attached to a HTTP or HTTPS server. I would advise you to use a HTTPS server as it helps prevent possible connection blocking by proxy servers. Most people don’t run HTTPS inside Node.js as it’s slower than a HTTPS terminator. We’re just gonna go with a simple HTTP server:

‘use strict’;var Primus = require(‘primus’)
, http = require(‘http’);
var server = http.createServer()
, primus = new Primus(server, { transformer: ‘websockets’ });

As you can see from the example we need to specify the transformer we want to use. Transformers are the real-time frameworks you wanted use. Now that we’ve created our server we need to listen for incoming real-time connections:

primus.on(‘connection’, function (socket) {
socket.on(‘data’, function ping(message) {
console.log(‘recieved a new message’, message);
socket.write({ ping: ‘pong’ });
});
});
server.listen(8080); // And listen on the HTTP server.

This is all you need to accept an incoming connection, receive data and send a reply. What’s really cool about primus is that it automatically takes care of encoding and decoding your messages. The only thing that’s left to do is build a HTML page and connect to the server.

<!doctype html>
<html lang=”en”>
<head>
<meta charset=”utf-8">
<title>Primus</title>
<— The client is automatically served by primus. —>
<script src=”/primus/primus.js”></script>
</head>
<body>
<p>
Welcome to Primus example.
</p>
<script>
var primus = new Primus(‘http://localhost:8080/?query=string’);
primus.write(‘you can write directly, we will queue it’);
primus.write(‘until the open event is called and flush it’);
primus.on(‘reconnect’, function () {
console.log(‘primus: reconnect event happend’);
});
primus.on(‘open’, function () {
console.log(‘primus: connection established’);
primus.write(‘hello world’);
});
primus.on(‘error’, function (err) {
console.log(‘primus: error event’, err);
});
primus.on(‘data’, function (data) {
console.log(‘primus: received data’, data);
});
primus.on(‘end’, function () {
console.log(‘primus: connection closed’);
});
</script>

And that’s basically all you need to create a real-time server which is flexible and doesn’t lock you in to any framework.

Primus highlights

  • Primus makes it effortless to switch between real-time frameworks and message encoders/decoders.
  • It has a simple low level interface that’s compatible with the Node.js streams so you can pipe data back and forth.
  • It fixes inconsistencies and bugs in frameworks where needed. So using a real-time framework through primus will most likely run smoother and better than the original plain framework.
  • Has build and working reconnect using randomised exponential backoff.
  • Comes with a server-side client as well as front-end client for easy testing.

Primus is released as an open source module with an MIT license. It’s available at https://github.com/3rd-Eden/primus and is well documented.

It doesn’t matter if you’re building a real-time application or want to build a module on top of a real-time framework, Primus is here to do the heavy lifting and allows you to focus on building your application/module without having to worry about the framework that want to use.

--

--

Arnout Kazemier
The build

Founder of Observe.it, Lead Software Engineer at Nodejitsu and passioned open source developer.