Messaging and Websockets with Spring 4

March 21, 2014 by Michael

This is the third Post in my series Developing a web application with Spring Boot, AngularJS and Java 8.

My old application had a J2ME(!) companion on my dump phone that send my location to the app, showing it on the page.

This was 2009… Before my iPhone time.

Planning a longer bike tour in 2014, i wanted this feature back but i have not the slightest ambition on writing an iPhone app anytime soon, so i asked around on twitter and Darko came up with OwnTracks which uses the MQ Telemetry Transport protocol for publishing (and subscribing to) location updates.

So what ingredients do we need to implement this in a standalone Java application? Actually, not many. I’ve added Apache Active MQ, Spring JMS and Messaging as well as Spring Websocket support for the frontend fun:

Spring Boot has a managed dependency for ActiveMQ but only 5.7 which has some bugs regarding the MQTT broker, therefor i use 5.9.

With those components given, it’s incredible easy to configure brokers for:

  • STOMP over WebSocket
  • Local (VM based) messaging
  • External messaging via MQTT

like this

In the simples case you would now add @EnableWebSocketMessageBroker to a configuration class and be done, but i wanted to use

  1. My own broker
  2. A username/password protected broker
  3. Also use @EnableScheduling

1. To use a custom broker, implement WebSocketMessageBrokerConfigurer (or extend AbstractWebSocketMessageBrokerConfigurer) in a configuration class and configure the relay

If you do this, be sure to add “org.projectreactor:reactor-tcp” to you dependencies, otherwise a weird ClassNotFoundException pops up…

While you’re at it, configure the thread pool size for in- and outbound channels in #configureClientInboundChannel and #configureClientOutboundChannel according to your needs.

2. See above, just use a simple Java based approach to configure the embedded broker.

3. Now this is fun… If you use some scheduled jobs in your application as i do, you’ll end up with the following exception: “More than one TaskScheduler and/or ScheduledExecutorService exist within the context”. Yeah, great… If you don’t configure a default scheduler, the ScheduledAnnotationBeanPostProcessor tries to find all beans of type TaskScheduler or ScheduledExecutorService… If it finds none, it uses the default, if it finds one, uses this, if it finds more, everything breaks… @EnableWebSocketMessageBroker creates 2 schedulers… So you need to configure your own:

I wish there is more to say, but the rest is standard… Putting together some listener that reacts on incoming locations, calls the Spring Data Repository and uses SimpMessagingTemplate to notify all subscribed STOMP clients. For details regarding WebSocket and STOMP have a look at the Spring reference. As i didn’t have any luck with the Atmosphere frameworks in 3 different applications since 2011, i’m really happy how the Spring solution turned out. Maybe she is still a little buggy, but i’m quite sure this will be fixed.

At the moment the location site runs on an uberspace behind a proxy, but STOMP together with SockJS handles this situation gracefully (and are actually dead simple to use):

It’s amazing what you can achieve with Java and Spring with little effort those days.

2 comments

  1. jfarcand wrote:

    What was the issues you faced with Atmosphere? If you have the time, drop me an email, I’m curious to learn what didn’t worked for you.

    Posted on May 5, 2014 at 3:38 PM | Permalink
  2. Michael wrote:

    Hi Jeanfrancois,

    nice to hear from you.

    We had contact in 2011, back than i had really massive problems with the than current Tomcat Version, Atmosphere and Spring Security, namely mixed up sessions… Messages were send to the wrong clients and or with the wrong user id.

    I could look up those conversations but those problems are probably solved. For my own application i decided back then not to use push.

    Push support in Vaadin based on atmosphere didn’t work for us at all… Could be a problem between chair and keyboard, but i didn’t think so.

    Bottom line is: Although i did carefully read your tutorials on how to include which jar and which not, i was kinda frustrated.

    I read your tweets about broken messaging / push in Spring 4 and though i see that those problems exists, the system works well and is nicely integrated in the Spring infrastructure which i didn’t manage to achieve with atmosphere.

    Posted on May 5, 2014 at 5:05 PM | Permalink
Post a Comment

Your email is never published nor shared. Required fields are marked *