Play!ing (2.0) with Twitter Bootstrap, WebSockets, Akka and OpenLayers

| 10 Comments

For one of our client, we need to show a map with vehicles position updated in real-time.
So I began to make a prototype using Play! framework, with its latest released version 2.0, using the Java API. I started from the websocket-chat of the Play! 2.0 samples.

The purpose of the prototype is to show a moving vehicle on a map. The location of the vehicle is sent to the server through a REST call (at the end, it will be sent by an Android app), and the connected users can see the vehicle moving in real-time on their map.

First, let’s look at a small demo !

So, at first, to make the things a bit pretty, I decided to integrate Twitter Bootstrap (v2.0.1) using LessCss. For that, I used the tips from the following article (nothing difficult here).

Then, I integrated OpenLayers, a Javascript framework used for map visualization. I used the Google Maps integration example, and add some KML layers. This is done in the map.scala.html and maptracker.js files, nothing fancy here (it is pure Javascript, and I’m not an expert…).

The interesting part is the one using the WebSockets. On the client side, it is quite standard :

When the client receive a JSON data from the websocket, it moves the marker on the map. And if an error occurs on the websocket (the server is stopped for instance), a pretty error is displayed thanks to Twitter Bootstrap :

On the server part, the websocket is created by the Application controller, and is handled by the MapAnime.java Akka actor; it accesses Akka native libraries to deal with the events from the controller.

The “register” and “moveTo” methods are called by the controller, they send messages to the Akka system. These messages are processed by the “onReceive” method. For instance, when it receives a MoveMessage, it creates a JSON object with the longitude and the latitude and it is sent to the clients through the websockets.

I also quickly wrote a test class which parse a text file, and send REST requests with a new location to the server every 100ms.

The project is hosted on Github. It works with Google Chrome v17 and Firefox v11.

To test it,

The problem I need to solve now is that the application is not Stateless, because in the Actor, I store a Map of connected clients. Maybe I’ll need to look at Redis or something, any help would be greatly appreciated.

So in conclusion, I was able to quickly develop a working prototype, and I think I’ll try to use Play! 2.0 in several projects ;-)

What’s good:

  • Highly productive
  • Typesafe view templates based on Scala
  • LessCss integration
  • Akka integration
  • Compiled javascript with Google Closure Compiler
  • No need to learn Scala for the moment, hooray ! ;-)

To be improved:

  • The Scala compile times should be increased, because on my PC, it takes up to 4s to compile a view, and it breaks my flow (I use the “~run” command to gain 1s when switching from my IDE to my web browser)
  • The Scala compiler errors are cryptic
  • I cannot deploy the demo on Heroku because it does not support (yet ?) websockets

Update: A bit later, I discovered an article from @steve_objectify using similar technologies: http://www.objectify.be/wordpress/?p=341

Update 2: I was successfully able to deploy the app on a cloud platform which allows websockets, dotCloud, by using this method. The result can be see here : http://maptracker-ndeverge.dotcloud.com/map

Share Button

Nicolas Deverge Author: Nicolas Deverge

Artisan-développeur tendance maniaque de l'organisation

Ma phrase : "T'as pensé à déplacer ton Post-It sur le Scrum board ?"
Ma définition d'ekito : "Un melting pot de personnalités et de compétences"
Mes hashtags : #agile #leanstartup #playframework #mqtt #arduino"

10 Comments

  1. thanks very much for sharing ! it’s very usefull

  2. excellent article! it’s great to showcase the new play2 capabilities!

  3. Great stuff. Nice write up!

    According to your question: Heroku und WebSockets I can confirm that Heroku currently doest not support WS protocol. See ticket http://support.heroku.com/tickets/40910

    http://multikoop.blogspot.de/2012/01/playing-with-websockets.html

    Greets,
    Andreas

  4. @Andreas,

    thanks for the info (but the link on the support page is broken).

    I alsodeployed on RedHat Openshift, but same result as Heroku : websockets are not currently supported : https://www.redhat.com/openshift/community/content/websockets-support

  5. I’d just like to mention that blogs and wiki tnirees are not a replacement for real documentation. I understand that you want to get code out to the community as soon as possible, which is good, even if it means that the code comes before the documentation. But eventually documentation must follow, and it should be versioned, kept up-to-date, and be thorough. Example: I’m STILL trying to figure out how to deploy my WAR to Jetty and setup a virtual host. No matter what I do I always get the default test page. Google for jetty virtual host and the most relevant info points back to the Eclipse Jetty wiki which is not thorough enough. Seems like no one on the planet has ever set up virtual hosting in Jetty if you consider Google to be authoritative. I don’t mean to offend, I just wanted to get that off my chest.

  6. Thank you for sharing this article. It was very helpful for me to understand how I can combine OpenLayers and Bootstrap. But I need you additional help. I want to draw some polygons on a map. I modify your example and commited it on github (https://github.com/djonmayer/play21-osm.git). Now I’m able to draw and modify polygons. But how I can draw some polygons given by some point or loaded from database?

    Best Regards
    Djon

  7. Hi, great work and thanks. Although when I plug in UK lon and lats to the test files nothing happens with the test….is there something that needs to change for uk ? thanks alot

  8. Hi Martin,

    You can use http://itouchmap.com/latlong.html to get the Latitude and Longitude.
    Then edit, the “conf/integrationTest/testdata.txt” file, and add lines with the following format:
    long;lat

    (longitude fist, a semi-colon, and the latitude).

    Hope this helps :-)

  9. Regarding your statelessness problem, shouldn’t you create a new actor for each connected client ? This is how it is done in Reactive Stocks (a Typesafe Activator sample) : https://github.com/typesafehub/reactive-stocks-java8/blob/master/app/controllers/Application.java

  10. I didn’t know this approach, and it is very simple, I like it :-)
    Thank you !

Leave a Reply

Required fields are marked *.