Posts Tagged ‘akka’

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

The original post can be found on the ekito website.

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 :

var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket
var mapSocket = new WS("@routes.Application.mapsocket().webSocketURL(request)");

mapSocket.onmessage = function(event) {
    var data = JSON.parse(event.data);
        
    marker = moveMaker(map, marker, data.longitude, data.latitude);
        
}

// if errors on websocket
var onalert = function(event) {
    $(".alert").removeClass("hide");
} 

mapSocket.onerror = onalert;
mapSocket.onclose = onalert;

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.

public class MapAnime extends UntypedActor {

	static ActorRef actor = Akka.system().actorOf(new Props(MapAnime.class));

	Map<String, WebSocket.Out<JsonNode>> registrered = new HashMap<String, WebSocket.Out<JsonNode>>();

	/**
	 * 
	 * @param id
	 * @param in
	 * @param out
	 * @throws Exception
	 */
	public static void register(final String id,
			final WebSocket.In<JsonNode> in, final WebSocket.Out<JsonNode> out)
			throws Exception {

		actor.tell(new RegistrationMessage(id, out));

		// For each event received on the socket,
		in.onMessage(new Callback<JsonNode>() {
			@Override
			public void invoke(JsonNode event) {
				// nothing to do
			}
		});

		// When the socket is closed.
		in.onClose(new Callback0() {
			@Override
			public void invoke() {
				actor.tell(new UnregistrationMessage(id));
			}
		});
	}

	public static void moveTo(float longitude, float latitude) {

		actor.tell(new MoveMessage(longitude, latitude));

	}

	@Override
	public void onReceive(Object message) throws Exception {

		if (message instanceof RegistrationMessage) {

			// Received a Join message
			RegistrationMessage registration = (RegistrationMessage) message;

			Logger.info("Registering " + registration.id + "...");
			registrered.put(registration.id, registration.channel);

		} else if (message instanceof MoveMessage) {

			// Received a Move message
			MoveMessage move = (MoveMessage) message;

			for (WebSocket.Out<JsonNode> channel : registrered.values()) {

				ObjectNode event = Json.newObject();
				event.put("longitude", move.longitude);
				event.put("latitude", move.latitude);

				channel.write(event);
			}

		} else if (message instanceof UnregistrationMessage) {

			// Received a Unregistration message
			UnregistrationMessage quit = (UnregistrationMessage) message;

			Logger.info("Unregistering " + quit.id + "...");
			registrered.remove(quit.id);

		} else {
			unhandled(message);
		}

	}

	public static class RegistrationMessage {
		public String id;
		public WebSocket.Out<JsonNode> channel;

		public RegistrationMessage(String id, WebSocket.Out<JsonNode> channel) {
			super();
			this.id = id;
			this.channel = channel;
		}
	}

	public static class UnregistrationMessage {
		public String id;

		public UnregistrationMessage(String id) {
			super();
			this.id = id;
		}
	}

	public static class MoveMessage {

		public float longitude;

		public float latitude;

		public MoveMessage(float longitude, float latitude) {
			this.longitude = longitude;
			this.latitude = latitude;
		}

	}

}

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

Advertisements

¡Lanzamiento de Play 2.0!

Traducido del blog de Typesafe

¡Presentando Play 2.0!

En noviembre del año pasado anunciábamos que Play, el framework de alta productividad para Java y Scala, pasaría a formar parte del stack de Typesafe. Hoy, apenas unos meses más tarde, nos complace poder anunciar que Play 2.0 ya está disponible como parte del Stack Open Source de Typesafe en su versión 2.0, junto con el soporte comercial de la subscripción de Typesafe.

Veamos algunas de sus principales características.

Soporte nativo para Java y Scala

Mientras que la versión original de Play Framework estaba escrita principalmente en Java, ofreciendo soporte para scala a través de plug-in, Play 2.0 adopta Scala de una manera más decidida. No sólo el núcleo central de Play ha sido migrado a Scala, sino que esta nueva versión brinda un soporte de primer nivel para el desarrollo de aplicaciones web con Scala. De manera tal que la nueva versión del framework provee dos API totalmente completas: una para desarrolladores de Scala y otra para desarrolladores Java.

Un controlador hecho con Java

El mismo controlador usando Scala

Desarrollo rápido de aplicaciones

Una de las características que hacían a la “experiencia de usuario” del desarrollador Play de la serie 1.x, era la consola de desarrollo y el reporte de errores en el propio explorador web. Play 2.0 mejora estas prestaciones al permitirle al desarrollador ejecutar porciones de código, pruebas o scripts de la línea de comando interactuando directamente con el runtime de la aplicación, y también compilando muchas de las partes típicas de una aplicación web.

Interactuando con los modelos de una aplicación Play 2.0 desde la consola

Llevando la seguridad de tipos a un nuevo nivel

Una de las ventajas de utilizar un lenguaje estáticamente tipado para escribir aplicaciones de Play, es que el compilador podía verificar partes del código por usted, Es por ello que Play 2.0 utiliza por defecto un lenguaje de templates basado en Scala, incluso para aquéllos desarrolladores que usen Java como su principal lenguaje de programación. Esto no signifca que usted deba convertirse en un experto en Scala para escribir templates en Play 2.0. Pero ahí está Scala, sin que usted lo note, trabajando en su beneficio.

Play 2.0 lleva las verificaciones en tiempo de compilación y el chequeo de tipos todavía más a fondo. Las rutas (que definen los URLs y el mapeo con las acciones), los templates, e incluso los recursos de la aplicación web son compilados (utilizando LESS, CoffeScript y el compilador de Google Clousure), poniendo a su disposición un entorno de desarrollo unificado tanto para los desarrolladores del lado del cliente como para los del lado del servidor. El resultado de todo esto es que más errores serán detectados en tiempo de compilación, acelerando el proceso de desarrollo de aplicaciones web. También hará muchísimo más simple trabajar en proyectos grandes que involucren numerosos desarrolladores.

Example route compilation failure detection

Jugando limpio

Play 1.x implementaba muchas de sus originales ideas (como la implementación automática de propiedades para Java y la recarga dinámica de sus clases) utilizando técnicas que requerían un runtime específico para Play. En cambio, Play 2.0 adopta un enfoque mucho más estándar para el despliegue del runtime. Esto fue posible escribiendo parte del framework en scala, y también aprovechando prestaciones de SBT, la popular herramienta de Scala para la construcción y despliegue de aplicaciones.

Play 2.0 mantiene la misma experiencia de los usuarios de la versión 1.x acostumbrados a ejecutar “play new, run start”, al mismo tiempo que parte de una base más fácil de extender. Play 2.0 ya trae configurado un script de compilación que funcionará sin modificaciones en la mayoría de los casos, pero si usted necesita personalizar la manera en que su aplicación es construida y desplegada, tendrá las herramientas a su alcance para adapatarla a sus necesidades. Como resultado de todo esto, hallará que será mucho más simple desplegar sus aplicaciones de Play 2.0 en los escenarios más variados.

Elija tan sólo las partes que va a usar

Dado que el diseño de aplicaciones web ha evolucionado en gran medida en los últimos años, Play 2.0 está construido siguiendo un criterio modular que le dará gran flexibilidad a la hora de elegir la tecnología a usar. ¿No desea usar una base de datos? Puede simplemente deshabilitar el plugin DB. ¿Quiere usar su propio motor de templates? Simplemente agrégue el plugin. ¿No necesita un framework web con todos los chiches? Use play como una simple librería. Usted decide qué tanto de la arquitectura de Play quiere usar en sus aplicaciones.

Deshabilitando plugins en el archivo conf/application.conf

Escale su apliación con Akka

Play está basado en una arquitectura liviana, sin estado, pensada para la web, que le asegura un consumo de recursos mínimo y predecible (en términos de CPU, memoria, threads) para desarrollar aplicaciones que requieren alta escalabidad. Esto es posible en parte gracias a Akka 2.0, el middleware basado en eventos que se encuentra en el corazón de Play 2.0. Los desarrolladores tienen acceso a toda la funcionalidad provista por Akka para construir aplicaciones altamente distribuidas que puedan ser escaladas para cumplir con los más altos niveles de demanda.

En este ejemplo puede ver como el resultado de un actor encargado de realizar un cálculo complejo, puede ser mapeado a un resultado de Play de una manera no-bloqueante

En este ejemplo puede ver como el actor ChatRoom envía un mensaje en porciones al cliente utilizando Comet

Manejo avanzado de entrada/salida y de Streams

Una de las más recientes tendencias en el desarrollo de aplicaciones web es el énfasis puesto en tecnologías de tipo push y no-bloqueantes. Play 2.0 utiliza una implementación de entrada/salida basada en Iteratee, que provee soporte para tecnologías avanzadas de push y streaming, partiendo desde WebSockets y Comet hasta streaming de archivos.

Un controlador de scala que utiliza el soporte para WebSockets de Play 2.0

Listos… preparados… a jugar con Play!

Play 2.0 es el resultado de una intensa colaboración entre Typesafe (liderados por Peter Hausel), el fundador del proyecto Guillaume Bort, la comunidad Play y Zenexity, la consultora orientada a la web donde Play fue creado. Ha sido una experiencia divertida y excitante trabajar junto con un grupo tan talentoso de desarrolladores.

Estamos sumamente complacidos de que Play hoy sea parte del Stack de Typesafe, junto con Scala, Akka y el soporte comercial, mantenimiento y herramientas de despliegue y administración (como la nueva consola de Typesafe) que juntas conforman el paquete de Subscripción de Typesafe. Typesafe también ofrece cursos de capacitación y consultoría para la nueva versión 2.0, para que su equipo pueda cuanto antes comenzar a desarrollar aplicaciones con Play 2.0.

Estamos convencido de que el lanzamiento de Play 2.0 marcará un antes y un después en las comunidades de Java y Scala, poniendo al alcance de los desarrolladores una experiencia novedosa que posibilitará inéditos niveles de escalabilidad y productividad.

Para que pueda empezar ya mismo con Play 2.0, hemos provisto varias aplicaciones de ejemplo con esta nueva versión. Así que lo invitamos a verlo en acción para decidir por usted mismo, ¡y divertirse haciéndolo!

Ya que ha llegado hasta aquí, no pierda los anuncios recientes de la versión 2.0 del Stack de TypesafeAkka 2.0, y la Consola de Typesafe.

Para más información, lean el anuncio original en el blog de Typesafe

%d bloggers like this: