Set up a full broker for Spring 4 STOMP over WebSocket messaging using ActiveMQ

Spring 4 websocket comes with a built-in “simple” broker for handling messaging in memory. In this blog, I will demonstrate how to configure Spring 4 to use a “full” broker, i.e. ActiveMQ, to support STOMP over WebSocket messaging.

1. Enable ActiveMQ for STOMP

First, we need to enable STOMP protocol support in ActiveMQ. This can be done by adding the connector in the activemq.xml file as shown below.

 <transportConnectors>
       <transportConnector name="openwire" uri="tcp://0.0.0.0:61616"/> 
       <transportConnector uri="stomp://localhost:61613"/>
 </transportConnectors>

You may also setup security as mentioned in the ActiveMQ documentation here.

2. Add reactor-tcp jar files

Add to following dependencies to the pom.xml file:

 <!-- Reactor for websocket relay to MQ-->
 <dependency>
      <groupId>org.projectreactor</groupId>
      <artifactId>reactor-core</artifactId>
      <version>1.0.0.RELEASE</version>
 </dependency>
 <dependency>
      <groupId>org.projectreactor</groupId>
      <artifactId>reactor-tcp</artifactId>
      <version>1.0.0.RELEASE</version>
 </dependency>

Or download the jar files reactor-core-1.0.0.RELEASE.jar and reactor-tcp-1.0.0.RELEASE.jar into your classpath

3. Update Spring WebSocket config

Replace the simple broker config below

 <websocket:message-broker application-destination-prefix="/app">
       <websocket:stomp-endpoint path="/hello">
             <websocket:sockjs/>
       </websocket:stomp-endpoint>
       <websocket:simple-broker prefix="/topic,/queue"/>
 </websocket:message-broker>

with a full broker:

 <websocket:message-broker application-destination-prefix="/app">
       <websocket:stomp-endpoint path="/hello">
            <websocket:sockjs/>
       </websocket:stomp-endpoint>
       <websocket:stomp-broker-relay prefix="/topic,/queue"
           relay-host="localhost" relay-port="61613"
           heartbeat-send-interval="20000" heartbeat-receive-interval="20000"/>
 </websocket:message-broker>

If you setup security in ActiveMQ, you will also need to include the attributes client-login, client-passcode, system-login and system-passcode for connecting to  the broker on behalf of the client and the application respectively. By default, they are set as “guest”

Putting in altogether

That’s it. Now to test it out. first fire off ActiveMQ, you should see in the logger messages something like this:

INFO | Listening for connections at: stomp://messageserver:61613
INFO | Connector stomp://localhost:61613 Started

Now start the web server, I am using jetty 9. You should see the following logger message from reactor-tcp:

INFO : 12 Apr 2014 10:47:13,023 (reactor-tcp-io-3) reactor.tcp.netty.NettyTcpClient - CONNECT: [id: 0x71a8bfb1, /127.0.0.1:49617 =>       localhost/127.0.0.1:61613]
 ...
[INFO] Started Jetty Server

Now we are ready to send some messages to the full broker. I use the hello world application in my previous blog to send a message to the topic “greetings”. You should then see the topic created in the ActiveMQ admin console, e.g. http://localhost:8161/admin/topics.jsp.