RabbitMQ Web STOMP Plugin

The Web STOMP plugin is a simple bridge exposing the STOMP protocol over direct or emulated HTML5 WebSockets.

The main intention of Web-Stomp is to make it possible to use RabbitMQ from Web browsers. It influenced the Web MQTT plugin which is the same idea for a different protocol, MQTT.

More context is available in the introductory blog post.

How It Works

RabbitMQ Web STOMP plugin is rather simple. It takes the STOMP protocol, as provided by RabbitMQ STOMP plugin and exposes it using either plain WebSockets or a SockJS server (WebSocket emulation).

SockJS is a WebSockets poly-fill that provides a WebSocket-like JavaScript object in any browser. It will therefore work in older browsers that don't have native WebSocket support, as well as in new browsers that are behind WebSocket-unfriendly proxies.

Enabling the Plugin

rabbitmq_web_stomp plugin ships with RabbitMQ.

To enable the plugin run rabbitmq-plugins:

rabbitmq-plugins enable rabbitmq_web_stomp

Usage

In order to use STOMP in a Web browser context, a JavaScript STOMP library is required. We've tested a stomp-websocket library by Jeff Mesnil and Jeff Lindsay. This library is included as part of RabbitMQ Web STOMP examples.

By default the Web STOMP plugin exposes both a WebSocket and a SockJS endpoint on port 15674. The WebSocket endpoint is available on the /ws path:

http://127.0.0.1:15674/ws

The SockJS endpoint on the /stomp prefix:

http://127.0.0.1:15674/stomp

The SockJS endpoint is provided for compatibility purposes with older browsers that do not implement Websocket. It has two limitations because of SockJS:

The raw Websocket endpoint was created to provide an alternative that does not have these limitations. On the other hand, this endpoint will only work with Websocket capable clients. Note that some configuration is necessary in order to accept binary messages.

In order to establish connection from the browser using WebSocket you may use code like:

<script src="stomp.js"></script>
<script>

    var ws = new WebSocket('ws://127.0.0.1:15674/ws');
    var client = Stomp.over(ws);
    [...]

Using SockJS:

<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
<script src="stomp.js"></script>
<script>

    var ws = new SockJS('http://127.0.0.1:15674/stomp');
    var client = Stomp.over(ws);
    [...]

Once you have the client object you can follow API's exposed by stomp.js library. The next step is usually to establish a STOMP connection with the broker:

    [...]
    var on_connect = function() {
        console.log('connected');
    };
    var on_error =  function() {
        console.log('error');
    };
    client.connect('guest', 'guest', on_connect, on_error, '/');
    [...]

Web STOMP Examples

A few simple Web STOMP examples are provided as a RabbitMQ Web STOMP examples plugin. To get it running follow the installation instructions for that plugin and enable the plugin:

rabbitmq-plugins enable rabbitmq_web_stomp_examples

The examples will be available under http://127.0.0.1:15670/ url. You will see two examples:

We encourage you to take a look at the source code.

Configuration

When no configuration is specified the Web STOMP plugin will listen on all interfaces on port 15674 and have a default user login/passcode of guest/guest. Note that this user is only allowed to connect from localhost by default. We highly recommend creating a separate user production systems.

To change this, edit your Configuration file, to contain a tcp_config section with a port variable for the rabbitmq_web_stomp application.

For example, a complete configuration file which changes the listener port to 12345 would look like:

[
  {rabbitmq_web_stomp,
      [{tcp_config, [{port, 12345}]}]}
].

You can use the tcp_config section to specify any TCP option you need. See the RabbitMQ Networking guide and Ranch documentation for details about accepted parameters.

TLS (SSL)

The plugin supports WebSockets with TLS (WSS) connections. That requires Erlang/OTP 17.5 or a later version.

TLS (SSL) configuration parameters are provided in the ssl_config section:

[
  {rabbitmq_web_stomp,
      [{ssl_config, [{port,       15671},
                     {backlog,    1024},
                     {certfile,   "path/to/certs/client/cert.pem"},
                     {keyfile,    "path/to/certs/client/key.pem"},
                     {cacertfile, "path/to/certs/testca/cacert.pem"},
                     %% needed when private key has a passphrase
                     {password,   "changeme"}]}]}
].

Note that port, certfile, keyfile and password are all mandatory. See the TLS guide and Ranch documentation for details about accepted parameters.

A separate guide on TLS Troubleshooting is also available.

WebSocket Options and Content Encoding

By default, the Web STOMP plugin will expect to handle messages encoded as UTF-8. This cannot be changed for the SockJS endpoint, however you can switch the WebSocket endpoint to binary if needed. The ws_frame option serves this purpose:

[
  {rabbitmq_web_stomp, [{ws_frame, binary}]}
].

The Web STOMP plugin uses the Cowboy web server under the hood. Cowboy provides a number of options that can be used to customize the behavior of the server w.r.t. WebSocket connection handling. You can specify those in the Web STOMP plugin configuration, in the cowboy_opts section:

[
  {rabbitmq_web_stomp,
      [{cowboy_opts, [{max_keepalive, 10}]}]}
].

The SockJS endpoint can also be configured further in the sockjs_opts section of the configuration. Look into the SockJS-erlang repository for a detailed list of options you can use. For example, to use a different SockJS client version, you can use the following configuration:

[
  {rabbitmq_web_stomp,
      [{sockjs_opts, [{sockjs_url, "https://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js"}]}]}
].

The use_http_auth option extends the authentication by allowing clients to send the login and passcode in the HTTP Authorization header (using HTTP Basic Auth). If present, these credentials will be used. Otherwise, the default STOMP credentials are used. The credentials found in the CONNECT frame, if any, are ignored.

[
  {rabbitmq_web_stomp,
      [{use_http_auth, true}]}
].

Missing features

RabbitMQ Web STOMP is fully compatible with the RabbitMQ STOMP plugin, with the exception of STOMP heartbeats. STOMP heartbeats won't work with SockJS (WebSocket emulation).