Push notifications using Web-Stomp, RabbitMQ and Hutch

Let's look at how to send push notifications through web-sockets using a tool we love, RabbitMQ.

I've been using RabbitMQ and Hutch to do service to service messaging for quite some time now and it has been working great so far. I just find out you can also do service to client messaging thanks to the Stomp protocol. Sounds great, let's take a look.

The Stomp protocol

I actually had no idea what was the Stomp protocol before. Without entering into too much detail, it's defined as a Simple (or Streaming) Text Orientated Messaging Protocol.

Feel free to have a deeper look on their github page.

RabbitMQ Web-Stomp Plugin

This is where the magic happens. RabbitMQ expose the Stomp protocol through a simple plugin called rabbitmq_web_stomp.

They use a server called SockJS under the hood that emulates traditional WebSocket. WebSocket technology is catching up, but it will take a while before all browsers support it. Feel free to have a closer look about SockJS, though it's not necessary for the purpose of this article.

The main intention of Web-Stomp is to make it possible to use RabbitMQ from web browsers.

Ok, now what?

Well it's time to put the pieces together and start pushing real-time messages from service to web browsers don't you think?

Installing Web-Stomp

Assuming you already have rabbitmq installed, all you have to do is to install the rabbitmq_web_stomp plugin:

rabbitmq-plugins enable rabbitmq_web_stomp  

Restart rabbitmq and make sure the plugin is installed by going to http://127.0.0.1:15674/stomp.

Usage

In order to use Stomp in a web-browser context, a JavaScript Stomp library is required. Let's just grab the one used in rabbitmq code samples here.

Now create a dummy html application and add the following javascript code in your index.html:

<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>  
<script src="stomp.js"></script>  
<script type="text/javascript">  
    var ws = new SockJS('http://127.0.0.1:15674/stomp');
    var client = Stomp.over(ws);

    client.heartbeat.outgoing = 0;
    client.heartbeat.incoming = 0;

    var onDebug = function(m) {
      console.log('DEBUG', m);
    };

    var onConnect = function() {
      client.subscribe('/exchange/my_app_development/test', function(d) {
        console.log(JSON.parse(d.body));
      });
    };

    var onError = function(e) {
      console.log('ERROR', e);
    };

    client.debug = onDebug;
    client.connect('guest', 'guest', onConnect, onError, '/');
</script>  

Ok that's it for the client code. We first create a new connection using the Stomp library providing a user named guest and his password guest on the rabbitmq vhost / (default rabbitmq parameters).

Then we subscribe to the exchange named my_app_development and the routing key test. Every time a message is send with that routing key, the function will be triggered and a JSON representation of the body will be printed to the web console.

Server side

Now that we've setup the client side to subscribe to events routed to test, we'd like to actually send messages using Hutch.

Let's create a new rails application for simplicity. Add the hutch gem to your Gemfile and run the bundle command:

gem 'hutch'  

Now let's configure hutch. Add your rabbitmq configuration to config/initializers/hutch.rb:

Hutch::Logging.logger = Rails.logger

Hutch::Config.initialize  
Hutch::Config.set(:mq_exchange, 'my_app_development')  
Hutch::Config.set(:mq_username, 'guest')  
Hutch::Config.set(:mq_password, 'guest')  
Hutch::Config.set(:mq_host,     'localhost')  
Hutch::Config.set(:mq_vhost,    '/')  
Hutch::Config.set(:mq_api_host, 'localhost')  
Hutch::Config.set(:mq_api_port, 15672)  
Hutch::Config.set(:mq_api_ssl,  false)  

Here for simplicity I used the default rabbitmq parameters.

Great, you should be all set to start pushing new messages. Let's go through the checklist:

  1. Make sure your rabbitmq server is running
  2. Make sure you've installed the web-stomp plugin by going to http://127.0.0.1:15674/stomp
  3. Open your dummy index.html and watch the web-console for any errors
  4. Open a new rails console and run Hutch.connect
  5. Run Hutch.publish('test', { message: "Hello World!" })

You should see the message appear in your web-console:

Object {message: "Hello World!"}  

What we've learn

Today we saw it is possible to use a tool we used for service to service messaging to push messages directly to web-browsers using the same code server side.

Using Hutch and a JS library called SockJS, we were able to send real-time messages from our server directly to our client browser.

To go even further, note that it is also possible to send message from the browser directly to your server using client.send('routing_key', {}, data). This also means that to use Web-Stomp in any production environment you should create at least one user, with limited permissions, or a new vhost which you can expose publicly, because the username/password must be included in your javascript, and non-limited user can subscribe and publish to any queue or exchange.

Show Comments