Connecting Websockets with HornetQ in JBoss EAP 6.1

In today’s post I will walk through a showpiece how to connect a web client to the JBoss messaging services using Websockets. To give you an overview on what is happening:

  • A Java EE application is built, which allows a client to subscribe to stock market quotes
  • The application will store the subscriptions and retrieves the current prices of the share on the stock market for the subscriptions
  • The subscriptions are pushed to the client where they are displayed in a simple table

The scenario is quite simplified for a real trade app, but you could imagine that – depending on the the service which delivers the current quotes of the shares and the frequency this service is queried – that the speed of delivery of the information is valuable to the client. Unfortunately services which are for real-time trading are not for free, so the implementation for our demo is limited.

On the technical side, the more interesting pieces are done like this:

  • The JEE application deliveres a simple web page (HTML and JavaScript) to the client for the user interface
  • There is a RESTful services which receives requests to store and delete the subscriptions
  • The subscriptions are stored in a SQL database (H2)
  • The quotes are retrieved from a free service offered by Yahoo (http://de.finance.yahoo.com/d/quotes.csv). If you are interested, here’s a documentation how that service works.
  • The retrieved quotes are pushed to JMS topic on the JBoss EAP 6.1 server (AS 7.2)
  • The web client subscribes to the JMS topic via Websockets, receives the message and renders the data into a table.
  • The messaging protocol is Stomp, the payload is JSON.

The real magic – or non-standard stuff – are the last two items. HornetQ – the messaging server within the JBoss AS7 – has the capabilities to use the Stomp protocol – and it also has a transport for websockets. And there is a nice JavaScript library which implements the Stomp protocol over websockets. All these pieces are very well explained in the documentation from Jeff Mesnil.

Now it’s time to put the things together. First you need JBoss EAP 6.1 – in JBoss AS 7.1 this won’t work, because of a missing feature in the netty libraries included. Next step is to enable the stomp protocol. In the standalone-full.xml configuration we need to add these two pieces:


<acceptors>
<netty-acceptor name="netty" socket-binding="messaging"/>
<netty-acceptor name="netty-throughput" socket-binding="messaging-throughput">
<param key="batch-delay" value="50"/>
<param key="direct-deliver" value="false"/>
</netty-acceptor>
<netty-acceptor name="netty-stomp" socket-binding="messaging-stomp">
<param key="protocol" value="stomp_ws"/>
</netty-acceptor>
<in-vm-acceptor name="in-vm" server-id="0"/>
</acceptors>

and


<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
...
<socket-binding name="messaging-stomp" port="61614"/>
...
</socket-binding-group>

This enables the stomp_ws61614. The we gonna add a queue named stocksQueue and a topic named topicQueue to the server.


<jms-destinations>
...
<jms-queue name="stocksQueue">
<entry name="queue/stocks"/>
<entry name="java:jboss/exported/jms/queue/stocks"/>
<durable>false</durable>
</jms-queue>
<jms-topic name="quotesTopic">
<entry name="topic/quotes"/>
<entry name="java:jboss/exported/jms/topic/quotes"/>
</jms-topic>
</jms-destinations>

When you start the server now you should see some lines in the log that the stomp over websockets protocol is opened for port 61614 and the two destinations are deployed, so we are ready to use them.

The Java code is pretty straight-forward so I’ll skip that here; have a look at the github link at the end for the full source.

On the client side it’s getting more interesting again. First we gonna include the stomp library together with our own code in the head of the web page.


<html>
<head>
...
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/stomp.js"></script>
<script type="text/javascript" src="js/stockmarket.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var supported = ("WebSocket" in window);
if (!supported) {
var msg = "Your browser does not support Web Sockets. This example will not work properly.
";
msg += "Please use a Web Browser with Web Sockets support (WebKit or Google Chrome).";
$("#connect").html(msg);
} else {
client.init();
}
});
</script>
...
</head>

As you see there is a check if the browser supports websockets, but nowadays most of them do. If in doubt, install Chrome.
In the next step we going to use the library. When initializing the Client, we will subscribe to the topic:


function Client() {
this.url = "ws://localhost:61614/stomp";
this.login = "guest";
this.passcode = "guest_12345!";
this.stocksQueue = "jms.queue.stocksQueue";
this.quotesTopic = "jms.topic.quotesTopic";
this.debug = false;
}

Client.prototype.init = function() {
...
this.connect();
}

Client.prototype.connect = function() {
var client = Stomp.client(this.url);
...
// the client is notified when it is connected to the server.
var onconnect = function(frame) {
...
client.subscribe(caller.quotesTopic, function(message) {
caller.onmessage(JSON.parse(message.body));
});
}
client.connect(this.login, this.passcode, onconnect);
}

In the usual style of JavaScript and JQuery, a lot of callbacks are declared. As parameters, we need to know the websocket url to connect to: ws://localhost:61614/stomp. Not quite as obvious are the name of the queues. Whatever names you have declared in the JBoss configuration file needs a prefix jms.queue.. And the messaging services in the JBoss are protected, so you need credentials. In my demo they are fixed.

The initializer first creates a Stomp client, then connects to the websockets service and then subscribes to the topic queue and declare that the function onmessage should be called on an incoming message. The message body will be parsed from JSON. The onmessage function is again pretty standard JavaScript.

Now all pieces are in place, and you can deploy the application, subscribe to some stock market shares and see how every 30 seconds an update is delivered to you page. If you open a new client – best on a second machine – you going to receive the same updates at the same time.

I’ve only explained the most interesting pieces of the application, you can find the full example at Github: https://github.com/kifj/stomp-test

Tagged : , , , , , ,

Leave a Reply