Monday, 30 November 2009

Real time web made easier with Lift

Lift is a Web application framework written in Scala. It borrows many good ideas from existing Web frameworks (Model View Controller, convention over configuration, etc...) while leveraging Scala properties to do cool things. Type inference allows you to write concise code, static typing enables many errors to be detected at compile time, built-in XML support makes XHTML and XML templating very easy, etc.... As Scala is based on the JVM, all you need to run a Lift app is a vanilla Servlet container such as Jetty.

An area where Lift really shines is when it comes to writing real time Comet-style applications, applications where a remote server pushes information back to the web browser. Lift takes care of the heavy duty JavaScript code which is required for this to happen and exposes it via a set of Scala abstractions which are very easy to use. I will illustrate what I mean with the code for a very basic web chat which is a simplified version of a demo that you can try out form the Lift website.

The chat application involves two classes of objects. The chat manager manages the chat room. It registers users leaving or joining the room as well as users posting new messages. The chat user models a user connected to the room. It provides a simple Web UI to enter a message and to see the list of messages posted to the room so far by all participants. There is one chat manager and for this demo to be any useful, there ought to be one or more chat users.

A quick word about how Lift generates web pages. When a Web browser loads the chat room URL, Lift generates the output of the request by processing a static template written in XHTML. The template does not contain any code, but instead contains references to snippets of code which are methods in Scala objects that you implement. Here is what the XHTML template looks like.

To generate the HTML that will eventually be loaded by the browser, Lift creates an instance of ChatUser in the Servlet container, invokes its render method and inserts the resulting XHTML at the right place in the template. Lift takes care of creating instances of the ChatUser class as Web browsers connect to the chat room and it takes care of garbage collecting them when no longer needed.

Below is the code for the ChatUser.

Below is the code for the Chat Manager.

Unlike the ChatUser, the ChatManager is a vanilla Scala actor and not a CometActor as it does not have corresponding Web browser code.

It might be a bit tricky to understand what's happening. Lift creates a ChatUser object in the Servlet container per browser connected to the chat room. Each ChatUser object renders a simple Ajax form and a list of messages which are displayed in the UI of its corresponding Web browser. The text the user enters in the browser form is sent back over the wire via an asynchronous HTTP request to the ChatUser. The ChatUser then forwards the message to the ChatManager using the actor style message passing. The ChatManager in turn forwards all messages received so far back to all ChatUsers. In turn, each ChatUser pushes back the HTML table with the updated list of messages to its associated browser , all of this happening without the browser having to refresh.

And this is it. Lift takes care of all the heaving lifting :-) behind the scenes to make Comet processing easy. I hope this conveys all ridiculously simple it is to create Comet app using Lift. This code works on Safari, Firefox and even on an iPod without any modification.

If you want to find out more how Lift works here is a really good article which provides a lot more details:

No comments:

Post a Comment