Twitter Logo Follow us on Twitter
Project Information About this project

Server Push

The Challenge

Sometimes it's necessary to “push” UI updates from the web server to the browser client. As an example, imagine a chat application that notifies the user of a chat request from a peer.

Usually, the UI is updated in the UI thread as a result of a user interaction, e.g. in a listener. These updates are processed during request processing, so that the UI changes are immediately rendered in the response. But when the UI is updated from a background thread using Display.asyncExec() while the user is idle, there's no request that could fetch the UI updates from the server.

HTTP is not designed to push data to the client. An HTTP server can only answer requests from a client, but it cannot actively send any message to the client. In modern browser there is the WebSocker API which solves this problem in a standardized way, but browser support has yet to hit a state where it would efficiently implementable in RAP. There are basically two different approaches to tackle this problem, polling and Comet.

Polling

One approach would be to make the client issue requests at a steady interval. If any changes have occurred to the UI on the server, the server will send the UI updates in response. This can also be achieved in RAP, but is not officially supported. However, this is only an option when updates doesn't have to come timely. More importantly, the shorter the interval, the more network load is added by sending unnecessary requests frequently. It is therefore often not a effective solution.

UI Callback ("Comet")

With the so-called Comet approach, the server is able to notify the client immediately without the need for frequent requests. The basic idea is that the client sends a special “callback” request to the server. This request is not answered by the server, so the client keeps waiting for a response. When the server needs to notify the client of a change, it sends a response to the standing request and asks the client to call back.

RAP provides an implementation of this mechanism which is called UI callback. Before starting a background task, the UI callback can be activated by calling:


  UICallBack.activate( "my unique id" );
  

This has to be done from the UI thread, since otherwise the activation cannot be transferred to the client anymore. The id passed to the activate method is only needed to identify the caller. It has to be unique within the current session and should have a meaningful name, for example one that identifies the reason why the UICallBack is activated. After the background task has completed and the UI callback is no longer needed, it should be deactivated using the same id:


  UICallBack.deactivate( "my unique id" );
  

When different instances require the UI callback at the same time, only one standing request will be opened by the client. The UI callback system is deactivated only when the last instance has called deactivate.

More technical details of the UI callback implementation can be found on the UI Callback wiki page.