Introducing RabbitMQ-Web-Stomp
For quite a while here, at RabbitMQ headquarters, we were struggling to find a good way to expose messaging in a web browser. In the past we tried many things ranging from the old-and-famous JsonRPC plugin (which basically exposes AMQP via AJAX), to Rabbit-Socks (an attempt to create a generic protocol hub), to the management plugin (which can be used for basic things like sending and receiving messages from the browser).
Over time we've learned that the messaging on the web is very different to what we're used to. None of our attempts really addressed that, and it is likely that messaging on the web will not be a fully solved problem for some time yet.
That said, there is a simple thing RabbitMQ users keep on asking about, and although not perfect, it's far from the worst way do messaging in the browser: exposing STOMP through Websockets.
STOMP + Websockets
We're delighted to introduce a new plugin for RabbitMQ:
It is basically a bridge between RabbitMQ-STOMP plugin and a Websockets server (SockJS). Hopefully, it is a decent solution for a set of rabbit-on-the-web use cases.
What it actually does
Within RabbitMQ
RabbitMQ-Web-Stomp is a simple beast. It takes the STOMP protocol as provided by the RabbitMQ-STOMP plugin and exposes it using the SockJS server.
Wire protocol
One can connect to the SockJS endpoint from any browser using the reliable SockJS protocol. This will work even in browsers that don't support native websockets or in environments behind broken proxies that block non-http transports.
Alternatively, for users that don't need this level of sophistication, SockJS exposes a raw websockets url that can be accessed directly from a recent, websocket-capable browser.
In the browser
Within the browser, the connection to SockJS endpoint is basically a raw STOMP connection. You can send and receive normal STOMP frames.
Any decent javascript STOMP library should be able to handle that. For our examples we're using the stomp-websocket library by Jeff Mesnil and Jeff Lindsay.
We use this code in the examples:
<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
<script src="stomp.js"></script>
<script>
WebSocketStompMock = SockJS;
var client = Stomp.client('http://127.0.0.1:55674/stomp');
[...]
Installation
Rabbitmq-Web-Stomp is an experimental plugin. It's not distributed with vanilla RabbitMQ releases; you need to install it manually.
- You need at least Erlang R14 (more info).
- You need Rabbitmq-server 2.8.2 installed
- Grab the needed erlang plugin .ez files:
wget \ http://www.rabbitmq.com/releases/plugins/v2.8.2-web-stomp-preview/cowboy-0.5.0-rmq2.8.2-git4b93c2d.ez \ http://www.rabbitmq.com/releases/plugins/v2.8.2-web-stomp-preview/sockjs-0.2.1-rmq2.8.2-gitfa1db96.ez \ http://www.rabbitmq.com/releases/plugins/v2.8.2-web-stomp-preview/rabbitmq_web_stomp-2.8.2.ez \ http://www.rabbitmq.com/releases/plugins/v2.8.2-web-stomp-preview/rabbitmq_web_stomp_examples-2.8.2.ez - Next, copy them to the plugins directory. For example, on my Ubuntu box this will be:
sudo cp *.ez /usr/lib/rabbitmq/lib/rabbitmq_server-2.8.2/plugins - Now, you're ready to enable them using rabbitmq-plugins:
sudo rabbitmq-plugins enable rabbitmq_web_stomp sudo rabbitmq-plugins enable rabbitmq_web_stomp_examples - Restart the rabbitmq server. On ubuntu:
sudo /etc/init.d/rabbitmq-server restart
As you may have noticed, we enabled two plugins:
- First, RabbitMQ-web-stomp, which is the main plugin. It exposes SockJS endpoint on port 55674, like: http://127.0.0.1:55674/stomp.
- Second, RabbitMQ-web-stomp-examples, which only hosts a few javascript and html files with examples. This is accessible under: http://127.0.0.1:55670/.
Keep in mind, that RabbitMQ-web-stomp depends on RabbitMQ-STOMP which by default will bind to port 61613.
The usage
If you enabled RabbitMQ-web-stomp-examples plugin, you should be able to instantly run two examples prepared by us. Just open a web browser at http://127.0.0.1:55670/.
- "echo" - shows how to use STOMP to do
simple message broadcasting (source)

- "bunny" - example of a simple
collaboration canvas painting app (source)

Summary
RabbitMQ-web-stomp is quite a simple plugin, but opens wide possibilities, exposing the STOMP protocol to the browser.
Like always, feedback welcome. We're also looking for inspiration for more examples!


May 25th, 2012 at 10:50 am
That solution sounds really great! Congrats for the idea and its smart implementation.
Under integration on my side. Last point would consist in extending an existing JS logging framework with an integrated SockJS+STOMP logs appender!
Thank you
May 28th, 2012 at 2:35 pm
I mashed up an web log viewer with log.io and fluentd + amqp plugin.
June 4th, 2012 at 8:47 pm
It fails on this step :
$ sudo rabbitmq-plugins enable rabbitmq-web-stomp
Error: The following plugins could not be found:
rabbitmq-web-stomp
What did I do wrong ?
This is the plugins directory :
$ ls -l /usr/lib/rabbitmq/lib/rabbitmqserver-2.8.2/plugins/
total 2040
-rw-r--r-- 1 root root 216097 2012-04-27 21:40 amqpclient-2.8.2.ez
-rw-r--r-- 1 root root 221600 2012-06-05 02:45 cowboy-0.5.0-rmq2.8.2-git4b93c2d.ez
-rw-r--r-- 1 root root 99293 2012-04-27 21:40 eldap-2.8.2-git.ez
-rw-r--r-- 1 root root 48806 2012-04-27 21:40 erlando-2.8.2.ez
-rw-r--r-- 1 root root 213176 2012-04-27 21:40 mochiweb-1.3-rmq2.8.2-git.ez
-rw-r--r-- 1 root root 17059 2012-04-27 21:40 rabbitmqauthbackendldap-2.8.2.ez
-rw-r--r-- 1 root root 10584 2012-04-27 21:40 rabbitmqauthmechanismssl-2.8.2.ez
-rw-r--r-- 1 root root 7451 2012-04-27 21:40 rabbitmqconsistenthashexchange-2.8.2.ez
-rw-r--r-- 1 root root 95153 2012-04-27 21:40 rabbitmqfederation-2.8.2.ez
-rw-r--r-- 1 root root 8222 2012-04-27 21:40 rabbitmqfederationmanagement-2.8.2.ez
-rw-r--r-- 1 root root 2892 2012-04-27 21:40 rabbitmqjsonrpc-2.8.2.ez
-rw-r--r-- 1 root root 67233 2012-04-27 21:40 rabbitmqjsonrpcchannel-2.8.2.ez
-rw-r--r-- 1 root root 52947 2012-04-27 21:40 rabbitmqjsonrpcchannelexamples-2.8.2.ez
-rw-r--r-- 1 root root 375215 2012-04-27 21:40 rabbitmqmanagement-2.8.2.ez
-rw-r--r-- 1 root root 16561 2012-04-27 21:40 rabbitmqmanagementagent-2.8.2.ez
-rw-r--r-- 1 root root 32469 2012-04-27 21:40 rabbitmqmanagementvisualiser-2.8.2.ez
-rw-r--r-- 1 root root 25697 2012-04-27 21:40 rabbitmqmochiweb-2.8.2.ez
-rw-r--r-- 1 root root 36521 2012-04-27 21:40 rabbitmqshovel-2.8.2.ez
-rw-r--r-- 1 root root 13001 2012-04-27 21:40 rabbitmqshovelmanagement-2.8.2.ez
-rw-r--r-- 1 root root 86842 2012-04-27 21:40 rabbitmqstomp-2.8.2.ez
-rw-r--r-- 1 root root 42097 2012-04-27 21:40 rabbitmqtracing-2.8.2.ez
-rw-r--r-- 1 root root 17849 2012-06-05 02:45 rabbitmqwebstomp-2.8.2.ez
-rw-r--r-- 1 root root 48201 2012-06-05 02:45 rabbitmqwebstompexamples-2.8.2.ez
-rw-r--r-- 1 root root 59 2012-04-27 21:40 README
-rw-r--r-- 1 root root 44465 2012-04-27 21:40 rfc4627_jsonrpc-2.8.2-git.ez
-rw-r--r-- 1 root root 97673 2012-06-05 02:45 sockjs-0.2.1-rmq2.8.2-gitfa1db96.ez
-rw-r--r-- 1 root root 132332 2012-04-27 21:40 webmachine-1.7.0-rmq2.8.2-hg.ez
June 4th, 2012 at 8:49 pm
I found it, it should be like this:
$ sudo rabbitmq-plugins enable rabbitmqwebstomp
$ sudo rabbitmq-plugins enable rabbitmqwebstomp_examples
Please update the article. Thank you
June 4th, 2012 at 10:50 pm
Thank YOU very much for this plugin !!
It works flawlessly, even on Android 2.3 mobile browser ^_^ Loving it !!
At first I tried Atmosphere, JMS, HornetQ, Camel, and combinations thereof...
but this one RabbitMQ coupled with Stomp-Web's stomp.js and SockJS works wonderful :
https://github.com/soluvas/primefaces-bootstrap/commit/cc020d8c604756bbd976caa3f37a5bfb044f23c8
My server-side code is now very simple (just publishing/consuming RabbitMQ exchanges), and the client-side JavaScript code is also very simple (just subscribe to a bunch of Stomp destinations). Right now I'm declaring exchanges but I think a much better way for my usecase is just to use AMQP Topics so I can have dynamic routing keys. I think this will scale to a huge number of topics.
Thank you Marek !
P.S. Are you the Marek from SockJS fame ?
June 5th, 2012 at 8:42 am
Fiy, I have updated the stomp-websockets[1] JavaScript library and it impacts the client code.
The WebSocketStompMock variable was a hack to be able to test the lib using a mock stomp web
server.
I replaced it with a variable "WebSocketClass" inside the Stomp object to use another WebSocket implementation than the one provided by the Web browser.
This means you must now specify:
Stomp.WebSocketClass = SockJS;
client = Stomp.client(url);
That makes for better encapsulated code.
--
jeff
[1] https://github.com/jmesnil/stomp-websocket
November 28th, 2012 at 7:21 pm
Sorry, I didn't have any response in http://127.0.0.1:55670/ and http://127.0.0.1:55674/stomp, but i changed port to 155670 and 155674, and all is working. If this is not error in text write me about it.
Thank you for a very good plagin.
December 8th, 2012 at 8:53 pm
Cool, downloading your Web Stomp now. It seems too easy to use. I'll report back when I get the time.