BlogRuby on RailsSoftware Development

STOMP / ActiveMQ communication for Ruby / Rails applications

By January 7, 2016 March 27th, 2017 No Comments

Using messaging protocol to facilitate communication between different applications is nothing new, in fact it has been de facto standard for fast and reliable communication.

Introduction

Using messaging protocol to facilitate communication between different applications is nothing new, in fact it has been de facto standard for fast and reliable communication. It is important to note, this is type of communication which you would usually use when communicating between different hosts. When working on single host, there are simpler and more scalable methods that you can use (e.g. sockets).

What is needed

Let us take example of three applications running on two different servers. To simplify this example, one application will be master and other two will serve as slaves. Master application will provide work tasks, which will slave execute and report back progress. Seems simple enough, let us make it happen.

active_mq

Message Bus, enter ActiveMQ

ActiveMQ is one of the most popular solutions for open source messaging, there are some other popular alternatives such as RabbitMQ, Zer0MQ, etc. Following examples will be less so oriented on underlying technology, and more so on functional examples that will use STOMP. STOMP is a protocol, and as long as messaging server supports that protocol you should be able to change it.

Installing ActiveMQ is really simple, just follow getting started guide. After ActiveMQ has been installed we will need to make some adjustments to its configuration. Communication between master and slave will be implemented via two channels, one for broadcasting messages to slaves and one for replies from mentioned slaves.

In messaging there are two major types of communication channels topics and queues. Rules of thumb would be if you would like to broadcast messages you would use topics, if you wanna process messages in ordered fashion you would use queues. For our example it would be good to broadcast messages to slaves via topic and to process their results via queue.

Since we are clear on what to do, let us create topic and queue on ActiveMQ. After successfully installing ActiveMQ you can find it’s configuration in /opt/activemq/conf/activemq.xml.

Change configuration by adding above snippets and restart ActiveMQ, sudo service activemq restart. Important thing to note is when we define topic/queue as myapp.> this allows us to create multiple topics/queues under that namespace e.g. myapp.reply or myapp.foo.bar.reply.

Connecting to message bus

For interaction via STOMP we are going to use stomp gem, for more streight forward and simple approach. As gem’s README points out this is really simple to do. I am going to assume that you are running ActiveMQ locally with default port localhost:61613 our example will reflect that.

Pretty simple so far now let us publish message from our master node to topic myapp.work.

On the slave side we need to listen for these messages, or subscribe to them so we do that by initializing client and subscribing.

That is all functional pieces that we need to create more complex applications. There is convention that we in ABH use and that is replying to messages to queues with reply suffix. For this master and slaves relationship, or slaves would reply to queue /myapp/reply and master node would have responsibility to handle these messsages.

Note

Keep in mind that demonstrated solution had blocking properties, and as such might not be the best solution for Rails stack. For Rails I would recommend EventMachine based STOMP client. If enough interest has been shown I can write article on how to implement this solution in existing Rails applications.

Keeping track of sent messages

One important detail that should be included is request_id for messages that will be going between master and slaves. That is the simple way to keep track of jobs that were dispatches to slaves and their results. You can create UUID by using:

That way when you receive response on queue /myapp/reply you can match it to sent request.

Conclusion

Hopefully this will be enough to get you started. This article can be easily extended by previously mentioned reactor based EM STOMP client or by adding security to message since if SSL is not used these will be easy to read if intercepted. If enough interest is shown, will expend this topic more.

Written by: Haris Krajina