Websockets with Spring 4

I am throwing the entire kitchen sink into a small web application that I am developing as part of this post – Spring Boot, Spring Integration, RabbitMQ and finally the topic of the post, the Websocket support in Spring MVC with Spring 4.

Real-time quake listing application

The final app will list the earthquake occurrences around the world and is updated in realtime(if a minute can be considered realtime enough), along these lines:
 
 
 
 
 
Screen Shot 2014-03-08 at 12.13.08 AM

Storing the Quake Information

The first part of the application is polling the data from USGS Earthquake hazards program every minute and storing it. I have chosen to store it directly into a RabbitMQ topic, which will be later used for the Websockets integration. Spring Integration is a great fit for the requirements of such a feature – using just configuration I can poll the USGS service providing a json feed of this information and write it to a RabbitMQ topic. This is how this flow looks:

quakepolling

and a raw complete Spring integration flow for the same is the following, the only code missing here is the configuration for rabbitmq which is part of another configuration file:

<import resource="rabbit-context.xml"/>
 <int:inbound-channel-adapter channel="quakeinfotrigger" expression="''">
  <int:poller fixed-delay="60000"></int:poller>
 </int:inbound-channel-adapter>

 <int:channel id="quakeinfo"/>

 <int:channel id="quakeinfotrigger"></int:channel>

 <int-http:outbound-gateway id="quakerHttpGateway"
     request-channel="quakeinfotrigger"
     url="http://earthquake.usgs.gov/earthquakes/feed/geojson/all/hour"
     http-method="GET"
     expected-response-type="java.lang.String"
     charset="UTF-8"
     reply-channel="quakeinfo">
 </int-http:outbound-gateway>

 <int-amqp:outbound-channel-adapter amqp-template="amqpTemplate" channel="quakeinfo" />

So, now that I have a flow which collects the Earthquake information and stores it into a RabbitMQ topic called “amq.topic” and internally plugs in a routing key of “quakes.all” to each of the quake information message, the next step is to figure out how to show this information dynamically on the browser application.

Presenting the Quake information

Spring Framework 4.0+ makes it easy to develop the web part of the application with the Websocket based messaging support now built into the framework. Spring 4.0 uses the STOMP as higher level protocol over raw websockets – I have included references which provide much more clarity on the details of the Websocket support.

In essence, Spring will act as a intermediary for the browser to subscribe to the RabbitMQ quakes topic and display realtime information as new quake information flows in, this diagram from the references sums this up well:

Full-Featured-Message-Broker

Spring 4 Websockets support with an external broker requires the broker to support STOMP protocol, which is easy to enable with RabbitMQ. With the STOMP support in RabbitMQ in place, the Spring MVC configuration looks like this:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

 @Override
 public void configureMessageBroker(MessageBrokerRegistry config) {
  config.enableStompBrokerRelay("/topic/");
  config.setApplicationDestinationPrefixes("/app");
 }

 @Override
 public void registerStompEndpoints(StompEndpointRegistry registry) {
  registry.addEndpoint("/quakesep").withSockJS();
 }
}
  • “/topic” is being registered as a endpoint where Spring acts as a gateway to the RabbitMQ STOMP support
  • “/app” is the application prefix where Spring MVC will listen for browser requests encoded within the STOMP message frame, in this specific instance I am not getting any requests from the UI and so this endpoint is not really used
  • “/quakesep” is the websocket endpoint

This is all that is required on the server side!

Now for the client to subscribe to the message in the RabbitMQ topic, I have implemented it along the lines of the sample in one of the reference articles. The sample uses sockjs client, a javascript library for websocket emulation in browsers.

This is how the javascript code to connect to the websocket endpoint “/quakesep” and subscribing to the “/topic/quakes.all” endpoint looks like. This internally registers a temporary queue with RabbitMQ for this websocket session and maps a AMQP routing key of “quakes.all” to this temporary queue, in essence sending all the quake messages to the temporary queue for the session.

function connect() {
      var socket = new SockJS('/quakesep');
      stompClient = Stomp.over(socket);
      stompClient.connect({}, function(frame) {
          console.log('Connected: ' + frame);
          stompClient.subscribe('/topic/quakes.all', function(message){
              showQuakeInfo(message.body);
          });
      });
  }

the showQuakeInfo function above simply displays fresh quake information when available from RabbitMQ.

springwebsockets

The entire sample was put together with Spring Boot, this has ensured that the dependencies declared in the pom file is kept to a bare minimum, the amount of configuration to start up the application is surprisingly small – essentially the WebSocketConfig code that I displayed above!

Resources

  1. Websocket architecture in Spring Framework
  2. Webinar on building Websocket based applications using Spring Framework

 

Reference: Websockets with Spring 4 from our JCG partner Biju Kunjummen at the all and sundry blog.
Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

2 Responses to "Websockets with Spring 4"

  1. user23 says:

    Hi. I’m newbie in Spring 4 websockets and trying to learn your post. I’m trying to run the sample code, but I’m having error. Connection refused. ? What should I do to run it properly?. Btw nice post. Thank you so much.

  2. Ken dG says:

    Hi!. Thanks for this. Great post. I just have one question, Is it efficient to use this technology for creating multiplayer games?

Leave a Reply


eight + = 9



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books