Event Driven AJAX - Part 1 - Pushing Server Side Events
Demonstration Quick Link
Event Driven AJAX is inspired by Comet to provide a mechanism for updating a page based on server side events, rather than waiting for user driven requests or client side polling. In this article an overview of the event driven AJAX concept is provided, along with a proof of concept demonstration of its use.
1. Overview
Update 2006.09.14: More and more artlicles are referrring to long polling (the technique described in this article) as a form of Comet.
Comet is able the "push" data to the client by keeping the initial HTTP response open indefinitely. It utilises the progressive rendering technique common in modern browsers to update the page by sending additional script elements whenever a server side event occurs. Event Driven AJAX uses a similar approach to Comet of having a long lived HTTP connection, however unlike Comet this connection is initiated using a XMLHttpRequest object and terminates when a response is received. This is also unlike traditional AJAX where the server processes a request and sends a response immediately. With Event Driven AJAX the server receives the request and if there is no data to send back to the client, it waits until a server side event occurs before sending a response.
The diagrams below illustrate the difference between traditional AJAX and event driven AJAX.
Event driven AJAX improves upon traditional AJAX by allowing updates to the page to be driven by what is occurring on the server, rather than by some arbitrary polling period or by user actions.
Event driven AJAX also improves upon Comet by using a new request after each response rather than a single long lived connection. This allows the connection to the server to be terminated and re-initiated at will (In the context of Comet, re-initiating the connection requires a page reload). The ability to re-initiate the server connection allows event driven AJAX to be used in situations where the hosting company does not allow control of the maximum execution time of a server side script (e.g. when PHP is run in safe mode). In such situations a timeout event can be sent before the page finishes executing. The event would then be handled by client side script and re-initiate the server connection.
2. Demonstration
The demonstration provided uses the event driven AJAX approach to provide in real time, the number of times the page has been loaded, the number of sessions created on that page (a weak approximation of unique visitors) and the current brightness of the background of the page. Users may:
- adjust the brightness of the page by clicking on the "Darken Page" and "Lighten Page" links respectively.
- connect and disconnect with the server by using the "Terminate Connection with Server" and "Connect to Server" links respectively. By default the connection to the server is initiated when the page has been loaded.
- turn debugging information on and off by using the "Turn Debugging On" and "Turn Debugging Off" links respectively. By default debugging is turned off.
2.1. Usage
To use the demonstration, load the page on two computers or within two browsers (each page must have it's own session for the demonstration to work).
- Click "Darken Page" or "Lighten Page" and notice the brightness change on both views of the page.
- Reload the page within one browser and notice the page hits increase in both views of the page.
- Click "Terminate Connection with Server" in one browser (browser A) and click "Darken Page" or "Lighten Page" in the other browser. Click "Connect to Server" in browser A and notice the brightness update to the correct value in browser A.
2.2. How it Works
The demonstration pushes data to the client by:
- sending a XMLHttpRequest (via a modified Sajax library) when the page is loaded, which executes a PHP function called getEvents on the server.
- The getEvents function checks the event queue:
- If there are events on the queue, it removes the events from the queue and returns them in an array
- Otherwise the function waits till there is at least one event to return at which point it removes it/them from the queue and returns it/them in an array.
- If the script times out, a array is return containing a timeout event.
- The javascript function gotEvents receives the response, updates the page accordingly and sends another XMLHttpRequest to execute getEvents
2.2.1. Page Hits
When the page is loaded "Page Hits" is incremented by the PHP function adjustValue, which results in a PAGEHIT event being placed on all other event queues.
2.2.2. Sessions Created
If this is the first time that page is being loaded for the current session, the PHP function adjustValue is used to increment "Sessions Created", which results in a SESSIONHIT event being placed on all the event queues.
2.2.3. Page Brightness
When the "Darken Page" or "Lighten Page" link is clicked, a XMLHttpRequest is sent that executes either the darkenPage or lightenPage PHP functions respectively. These functions call the PHP function adjustValue to decrement or increment the page brightness respectively, which results in a BRIGHTNESS event being placed on all the event queues.
2.2.4. Debugging
The debugging aspects of the demonstration do not communicate with the server. The "Turn Debugging On" and "Turn Debugging Off" links change the value of the javascript variable sajax_debug_mode to true and false respectively. The modified Sajax library prepends debugging information to the debugging element if the javascript variable sajax_debug_mode is true.
2.2.5 Theory and Practise
In theory and event driven AJAX implementation would an message bus (such as TIBCO Rendezvous or JMS) to send events to between sessions. When getting events from the message bus the script would simply block until an event is available. In practise this is not the case for this demonstration as the use of a message bus is outside the scope of this article. Instead the demonstration polls (using a 0.1s interval) three files (one for page hits, one for sessions created and one for brightness) and when changes are detected, events are created on the event queue. For this reason, the author expects the scalability of the demonstration to be particularly poor.
2.3 Source Code
The source code for the demonstration is available the BSD license.
- eventdrivendemo.php
- Sajax.php (modified from Sajax-0.12)
3. Scalability
Event driven AJAX shares the scalability concerns of Comet. Web servers have been designed to receive a request, process it and send a response, not to have many open connections with their scripts blocked (or polling) over a potentially long period of time. Event driven AJAX also has an extra scalability concern over Comet. Using Comet the same connection is used for each event. With event driven AJAX the connections is terminated when events are sent to the client, which then re-initiates the connection by sending a new XMLHttpRequest. The sending of a event to all clients thus effectively synchronises their next XMLHttpRequest. While web servers are designed to handle many simultaneous requests, it is not clear how they will perform when those requests are highly synchronised. Due the authors lack of expertise in this area, he defers to others to comment further on scalability issues.
4. Limitations
Event driven AJAX in it's current form does not handle multiple pages using the same session. If you open the demonstration in two tabs (or windows) of the same browser, you will notice that updates will go to one page or another, resulting in either one or both pages containing data that has not been updated. Ways to resolve this issue will be investigated in Part 2 of this series.
5. Conclusion
Event driven AJAX provides a new and relatively simple technique for "pushing" updates from the server to the client. Event driven AJAX is not however ready for prime time and will not be until it's issues around scalability have been addressed. Regardless of whether these scalability issues are resolved, it is the authors hope that at the very least this article inspires others in the same way the Alex Russel's article on Comet has inspired the author.
Technorati : AJAX, Event Driven, Event Driven AJAX
8 comments.
(Re)Introducing Javascript And Hidden Applets (JAHA) »« No Built-In Virtualization in OS X 10.5?












I had a long response written up but your script ate it when I refused to put my email in.
It’s backov a..t. tamedtornado.com
Here’s the short version:
I came up with this system myself recently for a game I am working on. However, after tearing my hair out the last day or two, I discovered it doesn’t work on Firefox. I confirmed this by checking your Demo, which also doesn’t work on Firefox. It does however work perfectly in IE.
Any workarounds?
@Jason. What exactly do you mean by “it doesn’t work on Firefox”. I’m using Firefox 1.5.0.6 and it works exactly as expected. Where is does fail is if you have the page open with two windows in the same browser. Part 2 will address this issue. Part of the soultion uses JAHA (see the article (Re)Introducing Javascript And Hidden Applets (JAHA)).
Nope, doesn’t work. I’m using Firefox 1.5.6. I have 3 tabs open, one is this blog page, and the other is your ajax demo. Clicking “lighten page” gets a blocked AJAX request. Repeatedly clicking gets a whole bunch of them. This is echoed by your debug log as well as XMLHttpRequest debugger.
It is in fact the exact same problem I have with my own codebase. If I switch to Firefox 2.0 or IE, the page works perfectly.
Interestingly enough, I just tried this on my Mac, and the same version of Firefox it works fine. Are you aware of any specific Firefox settings on my PC that might be causing this? Or a version incompatibility?
@Jason: That’s starting to look very weird. I’m running Firefox on XP SP2. Out of curiosity, try evendrivendemo2.php and let me know if you have the same problem (it’s the demo for the next article in this series).
Yep, the second one works fine - I’m guessing you’re doing some of the updating with that applet.
Without two requests going, obviously there’s no blocking problem. I had a friend run your page on his Firefox and it works fine, so apparently this is some glitch with this specific PC. Very annoying.
Hi,
Nice piece of code.
I need a favour. I am trying to fetch xml which will be parsed by javascript upon ajax call (xmlhttprequest). how ever on IE it works fine but it fails to work on firefox. any idea how to fix it? I think IE and firefox handel xml in different ways and this difference is the reason.
Hi Pradeep,
Sorry, but I don’t have the resources to help you.