Ajax technology has been around for quite some time now, and the development momentum has really started to pick up. More and more Web sites are being designed with Ajax in mind, and developers have started to push Ajax to its limits. With the advent of phenomena like social networking and collaborative reporting, a whole new set of demands has started to appear. Users like to be notified if any other user has made changes to any activity being watched. Or, if a Web site displays dynamic data, such as stock market prices, then all the users must be notified about the changes instantly.
These scenarios lend themselves to a general class of problem called "Server Push." Typically, the server is the central entity, which gets notified first of any changes that happen, and it's the server's responsibility to notify all of the connected clients about the changes. Unfortunately, HTTP is the defacto standard protocol for client-server communication, and it is a stateless and, in a sense, unidirectional protocol. All the communications in an HTTP scenario must be originated by a client and ended by the server, whereas the scenario that I am explaining requires the reverse. For a server push, I want the server to start the communication and send the data to the client. The HTTP protocol has no provision for this, and Web site application developers use ingenious ways to circumvent these problems, such as polling, where a client keeps contacting the server at a fixed (or configurable) interval of time to find if any new updates are available. Most of the time, these polls will be wasteful because the server will not have any updates. This does not come for free, and there are two problems associated with this approach.
- It's a huge waste of network resources. Each poll request typically
creates a TCP socket connection (unless HTTP 1.1 has its
keepAlivesetting as true, in which case a previously created socket is reused). The socket connection itself is expensive. On the top of that, each request carries some data over the network; if the request does not find any updates on the server, this data transfer is a waste. If there are other applications running on the client machine, these polls decrease the bandwidth available to transfer data. - Even if a request is successful and does bring an update back to the client, depending on the polling frequency, it may not be real-time. For example, let's say polling is configured to occur every 20 seconds, and just after a request is returned from the server an update happens. This update will not reach the client until the next request comes again in 20 seconds. Therefore, the updates that are present on the server, ready to be consumed by clients, have to wait for some time before that can happen. This wait could be unacceptable for applications that need to run as close as possible to real time.
Given these two problems, polling may not be an appropriate approach for enterprise applications requiring critical, real-time, server-side updates. In this article, I discuss various approaches that can be alternatives to polling. Each alternative works better in some scenarios than others. I'll explain these scenarios, as well as show a set of UIs where a real-time server push is required.
Server update techniques in Ajax applications
Let's look in some detail at common techniques used to update information from the server, which simulates a server push.
Short poll, or frequent poll, is just what I discussed in the beginning of this article. This approach may work best in the cases where:
- Enough bandwidth is available.
- Statistically, most of the time, requests find updates. For example, stock market data will generally always have an available update.
- HTTP 1.1 protocol is used. Therefore, the same socket connection is kept alive
and re-used with the
keepAlive=truesetting.
Long poll is another approach that is used to update server data. The idea here is that a client establishes the connection, the server holds back the connection (by making the request thread wait on some condition), and when the data is available the server sends the data through the held connection and then closes the connection. The client, upon receiving the updates, immediately re-establishes the connection, and the server repeats the process again. This way, the client and server ensure that one request is always pending, and an almost real-time communication is achieved. However, long poll suffers from the following disadvantages:
- Browsers generally allow 2 connections per server by default. In this scenario, one connection is always busy. Therefore, the UI is left with only one connection (that is, half the strength) to service user requests. This may cause performance delays for certain operations.
- Opening and closing of HTTP connections is still required,
which may be expensive in the case of non-persistent connection mode (
keepAlive=false). - It is almost real time, but not exactly real time. (Of course, you can never control external factors like network latency, which will always be present in any approach.)
Streaming channel is almost the same as long poll; the difference being that the server does not close the response stream. Rather, it intentionally keeps it open, giving an illusion to the browser that more data is yet to come. However, streaming channel has its own disadvantages:
- The biggest issue here is flushing. Traditionally, Web servers cache the response data and only send it after a sufficient number of bytes or chunk has been received. In this case, even if the application flushes the data, it may still be buffered by the server for optimization. Worse still, if there's a proxy server sitting between a client and server, then the proxy can buffer the data further for its own convenience.
- Some browser implementations may decide to close the socket on their own if they find it to be open for a longer duration. In such a case, the channel needs to be re-established.
Generally, the first issue is circumvented by attaching a garbage payload with every streamed response so that the response data is enough to fill the buffers. The second issue is circumvented by sending a "keep-alive" or "sync" message at constant intervals to fool the browser into thinking that data is coming at a slower rate.
Each of these solutions has their niche use cases. All of them have been used in some solutions over the Internet. However, they all suffer from the same problem: They lack scalability. Typically, to hold back a request, you need to hold back the thread processing the request because almost all of the application servers today perform blocking I/O. Even if they don't, Java™ 2 Platform, Enterprise Edition (J2EE) provides no standards to perform non-blocking I/O for the HTTP request and response. (With Servlets 3.0 APIs, this problem should be resolved as these APIs include Comet Servlets.)
What you need as of now is a non-blocking I/O (NIO) server sitting at the back, and client applications connecting through that. Because such a socket will be a pure TCP binary socket, it will achieve the following objectives:
- Because of NIO on the server side, much better scalability can be achieved.
- There are no issues of response buffering because this socket is under direct control of application.
Having said that, it is imperative to note four drawbacks to this approach:
- Because this is a binary TCP socket, the application cannot really make use of SSL security provided by the HTTPS layer. So, applications requiring data security may need to provide their own encryption facilities.
- Generally, the server socket will be run on a port different from 80, so there will be issues with firewalls that allow traffic only from port 80. Therefore, some port configuration may need to be done.
- Ajax clients cannot really open a TCP socket connection with the back end.
- Even if Ajax clients could perform an open function, they cannot understand binary content, as Ajax is for XML or JSON (text-based) formats.
What I am highlighting in this article is how you can actually circumvent the third and fourth issues. If you are okay with security and firewall issues, the rest of the issues can be dealt with. The benefits of doing so are enormous.
You achieve the maximum possible real-time (barring the external factors like network latency, and so on) server push behavior for your applications, and you achieve a pretty scalable solution in terms of the number of simultaneously connected clients.
Now, lets start exploring how you can address issues 3 and 4 from above.
Ajax cannot really resolve issues 3 and 4. Therefore, you need to get solutions using other RIA technologies. There are two RIA technologies that offer socket APIs that can interact with Ajax applications as well. These are Adobe Flex and OpenLaszlo. Fully introducing these technologies is really out of the scope of this article (see Resources for more information), but two features that these technologies provide are:
- Both are capable of opening a TCP binary socket with the back end
- Both can interact very well with Ajax applications (basically JavaScript) running in the same browser window
However, this only partially addresses your concerns. Yes, you can now open a socket, and, yes, you can now make Ajax applications use them, but Ajax applications still cannot deal with pure binary data. What about that? Well, it turns out that both of these technologies do offer a variant of the binary TCP socket called XMLSocket, which can be used to transfer pure XML data back and forth. That's exactly what you need. If these technologies could open a socket with the server and if they can transfer XML data, you're done. Ajax applications can make full use of that to simulate a real-time server-push feature. Take a look at how you would do that.
Implementing an Ajax server push
I'll explain this technique using two different tools: Adobe Flex and OpenLaszlo. First of all, you need to write a back-end server that can accept connections and cache them. You don't want to stray too far from the theme here, so keep the server blocking I/O-based.
You need to create a server socket that can accept connections at a predefined address:
Listing 1. Creating the server socket
public class SimpleServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress("localhost",20340));
Socket socket = serverSocket.accept();
}
} |
Here, I've bound the server socket at the localhost:20340 address. When a client connects to the server socket, it will give me a socket representing that connection. Flex clients will then ask for a policy file that is part of their security model. Typically, this policy file will look like Listing 2.
Listing 2. Flex client policy file
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" to-ports="20340"/>
</cross-domain-policy> |
Immediately after connecting, the Flex client will send a request for the
policy file. The request will contain just one XML tag:
<policy-file-request/>. In the response, you need to return this policy
file. The code in Listing 3 does just that.
Listing 3. Send policy file response
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress("localhost", 20340));
Socket socket = serverSocket.accept();
String POLICY_REQUEST = "<policy-file-request/>\u0000";
String POLICY_FILE = "<?xml version=\"1.0\"?>\n" +
"<!DOCTYPE cross-domain-policy SYSTEM
\"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n" +
"<cross-domain-policy> \n" +
" <allow-access-from domain=\"*\" to-ports=\"20340\"/> \n" +
"</cross-domain-policy>";
byte[] b = new byte[POLICY_REQUEST.length()];
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
dataInputStream.readFully(b);
String request = new String(b);
if (POLICY_REQUEST.equals(request)) {
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.write(POLICY_FILE.getBytes());
dataOutputStream.flush();
dataOutputStream.close();
} else throw new IllegalArgumentException("unknown request format " + request);
} |
This establishes a successful connection with the client. Now, the server can start a "handshake" kind of protocol with the client, in which it will typically assign a unique ID and send it to the client. After that, the server can cache the socket against the ID, and, at any time after that, if the server needs to push some data to the client, it can locate the socket by the ID and use its output stream. Fortunately, OpenLaszlo also uses the same policy-file-based mechanism and, hence, the same server code can work for both scenarios.
Now take a look at how you can create a Flex socket and then connect with Ajax applications.
Using Adobe Flex to open a client socket
The code in Listing 4 shows how you can open a client socket from Flex:
Listing 4. Open a client from Flex
var socket : XMLSocket = new XMLSocket();
// register events:
socket.addEventListener(Event.CLOSE, closehandler);
socket.addEventListener(Event.CONNECT, connectHandler);
socket.addEventListener(Event.OPEN, openHandler);
socket.addEventListener(ProgressEvent.SOCKET_DATA, readHandler);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
socket.connect("localhost",20340); |
After the call to socket.connect() is made, Flex
sends a request to the server for the policy file and expects an XML response.
When that's complete, the connection is established, and this socket can now be used
to push data from the server.
As the final piece in the puzzle, you will see how Flex can call Ajax as an
application. For this, you write a generic JavaSscript function that can
handle the server-side messages. Let's call this method handleServerMessageReceived(message). This method gets the XML code from
the server, and what this method does with the message is application-specific.
The code in Listing 5 shows how Flex can call JavaScript functions. This code
is for the readHandler method, which gets called
when a server XML message is received.
Listing 5. readhHandler code using handleServerMessageReceived(message)
public function readHandler(e : DataEvent) : void {
var message : XML = e.data as XML;
ExternalInterface.call("handleServerMessageReceived", message);
} |
That's all! It's as simple as that. You have created an XML socket connection. When the data arrives from the server, you can call some generic handler function in the Ajax application, which can process those messages. The full source code is available as a download (see Download).
Now, take a look at how OpenLaszlo can achieve the same objective.
Using OpenLaszlo to open a client socket
Because OpenLaszlo applications target both the Flash and DHTML platforms, their APIs and scripting language are somewhat similar to those of Flash and JavaScript. This is mainly for the convenience of Web developers who want to migrate to OpenLaszlo as an alternative for RIA.
OpenLaszlo provides two ways to create a persistent connection with the back end. One way involves using the ConnectionManager APIs provided as part of Lz (Short for Laszlo) standard libraries. However, their documentation clearly specifies the following:
"Warning: This feature is provisional. It works in limited capacity situations and is fine to develop with, but we do not recommend deployment (with the possible exception of low-capacity, non-mission critical deployment) with this feature. Please consult Laszlo Systems directly if you have questions about the robustness of an application that uses this version of the persistent connection."
Maybe it is an experimental technology right now, and in future versions of OpenLaszlo, it will be substantiated further.
The second way is similar to Flex, in which you manually open an XML socket connection and wait for the READ_DATA event to occur. Listing 6 shows how to do this.
Listing 6. Defining the XMLSocket class
<class name="ClientSocket" extends="node"> <attribute name="host" /> <attribute name="port" /> <XMLSocket name='xml_socket'/> <handler name="oninit"> // connect the socket here: xml_socket.connect(host,port); </handler> <handler name='onData' reference='xml_socket' args='messageXML'> <![CDATA[ ExternalInterface.call(‘handleServerMessageReceived',messageXML); ]]> </method> </class> |
(Other handlers are omitted for brevity. A complete code listing can be found in the download for this article.)
That's it. Creating a socket object and connecting it is as simple as that.
This code listing creates a new class called ClientSocket and then declares an XML socket object named
"xml_socket." Whenever this socket object reads data from the server, it will
fire an onData event that will be handled by the
handler defined for onData. Finally, in the onData handler, you call the external JavaScript
function residing in the Ajax application. From there on, the flow remains the
same as with the Flex client.
To create an ClientSocket object is as simple as
declaring it:
Listing 7. Declaring the ClientSocket
<canvas> <ClientSocket id='serverPushSocket' host='localhost' port='20340'/> </canvas> |
When the init event is fired for ClientSocket, it
attempts to connect to the back end at the specified host and port. (See
the oninit handler in Listing 6.)
In this article, I discussed various approaches for simulating a server push, ranging from pure polling to a real-time server push, and noted the strengths and weaknesses of each approach. Finally, I focused on one approach that gives the best results in terms of server scalability and real-time server push behavior.
Server push is not for every application. In fact, most of the applications fair very well in a normal request/response scenario. Others work adequately using polling and the similar techniques. It is only for those real heavyweight applications, where server updates are inevitable and clients need to be notified instantly, that you really need the techniques discussed in this article. It is again noteworthy to mention that this technique still suffers from two major drawbacks:
- The client socket cannot make use of SSL encryption facilities if the data needs to be transferred over HTTPS.
- Firewalls need to allow a non-standard port (other than 80) for client sockets to connect back to the server.
However, custom encryption routines can easily be written with so many open source libraries available in the market. Similarly, configuring a firewall is also not a big deal and is actually a small price to pay for getting such a strong capability as a real-time server push.
| Description | Name | Size | Download method |
|---|---|---|---|
| Source code | samples.zip | 9KB | HTTP |
Information about download methods
- Find out more about the binary socket API in
the Adobe Flash documentation.
- See more about the XML Socket API in the
Adobe Flash documentation.
- Get more information on configuring the
socket policy
file in the article, "Setting Up A Flash Socket Policy File."
- Read more about socket programming in
Chapter 24 of the book, "Action Script Cook Book."
- Learn more about OpenLaszlo persistent
connections at the product site.
- Get more information on Adobe
Flex.

Sandeep Malik is a Tech Lead for IBM Cognos NOW! and works out of India Software Labs, Pune. He has been involved in the design and architecture phase of new generation UI for the Cognos NOW!, and in memory and real-time streaming OBI (Operation Business Intelligence) engine. Sandeep has extensive experience in heavy duty graphics, charting libraries, client-side streaming, non-blocking I/Os, and in general, asynchronous systems. Prior to IBM, Sandeep worked in a network security domain, analyzing the patterns that change the network traffic distribution (for example, botnets, worm scans, and so on). He has also worked on implementing Servlets 2.4 spec in one of his previous companies. During his free time, he enjoys watching cricket and wishes that in his next life he could become a cricketer, too!
Comments (Undergoing maintenance)





