site logo

Monitoring device status with help of AJAX

This article is not AJAX tutorial, this is live, functional example of using AJAX technology in production firm intranet. In text you can find code samples and some comments about this technology using. To the study in depth I recommend set of articles Mastering Ajax on IBM developerworks server.

Example comes from intranet application melting glass, which was running since 2001 year. In schematic picture of glass tank are placed cells (frames) for real process values display. After page load, transfer and update of only real data starts (here in interval 5 sec.), all other page elements stays without change. Live (real, instant) data are read from database on server, where are recorded by melting control system.

Simplified home page of application follows. Only four measuring points are displayed here in example, compared to 16 points in original. Data here are created by the help of server random number generator, in original page are read from database. Real time in this page is server time. Description of measuring points and links to trend display pages are cut out in the example.

real time:

Example looks very similar as basic screen of melting control system for visualisation. This intranet page can be displayed in browser for many hours and all the time displays actual data. Then just flight look on screen is enough for finding whether production process is under control. Web application interface do not offer so high comfort as control system does, but we do not need expensive licences, hardware keys, nor software installation. This application fits for remote, or occasional check of glass tank status.

CSS code

Few notes to CSS code at first. Cells for value display are using class Lb. In CSS section is only definition of basic appearance and dimensions of this class. Position (location) of particular cells are defined later as inline style, when cell <div> elements are instantieted in HTML code.


<style type="text/css">
.Lb {font: 13px Arial, SansSerif, Verdana; text-align: center;
     position: absolute; width: 45px; height: 15px;
     border: 1px solid #ccc; background: #fff; color: #006;}
</style>

<body>
...
<div style="position: relative; width: 580px; height: 326px;">
<img src="tank.png" style="width: 580px; height: 326px;">

<div class="Lb" style="top:35px; left: 216px; width: 60px;
    border: 0; background: transparent;">real time:</div>
<div id="d0" class="Lb" style="top:  35px; left: 280px; width: 132px;"></div>
<div id="d1" class="Lb" style="top: 131px; left: 193px;"></div>
<div id="d2" class="Lb" style="top: 171px; left: 257px;"></div>
<div id="d3" class="Lb" style="top: 262px; left: 190px;"></div>
<div id="d4" class="Lb" style="top: 262px; left: 290px;"></div>
</div>
...
</body>

Schematic picture of equipment and measuring point cells are placed into element <div>, which serves as container for these elements. Container has position relative so as inside of this container it was possible to use position absolute, and properties top, left  for locating measuring point cells. Measuring point cells are situated approximately in corresponding sensor location. Each cell has assigned its own id according to the sequence of values in Ajax data message.

Browser script

Ajax scripts debugging is more difficult than debugging DHTML scripts, or form validation scripts. Partial routines run on separated computers (client / server) and interact by sending messages over network. First part of script creates and sends request (run at browser), second part receives request, creates and sends back response (server script) and third part of script receives response and interpret data message (again run at browser). Such a break-up of scripts make problems in error locating.

Majority tutorials use similar code with detail explanation, therefore I bring here only inevitable description. Data transfer is provided by the help of XMLHttpRequest object, which transfers either XML, or plain text data. In this example plain text is transfered. Entire data transmission is handled by two functions: Next() performs creation and initialization of req object, sets up response process function, sends request and sets timer for next data transmission. Function processReq() tests response status, processes response data and writes out received data to the appropriate cells. Remains only to start action by performing last statement (line 30) after page loading.


 1. <script type="text/javascript">
 2. var req, URL = "getStatus.asp";
 3. function processReq() {
 4.   if(req.readyState == 4) {
 5.     if(req.status == 200) {
 6.       var data = "";
 7.       data = req.responseText.split("|");
 8.       for(i=0; i<5; i++) {
 9.         document.getElementById("d" + (i)).innerHTML = data[i];
10.       }
11.     }
12.   }
13. }
14.
15. function Next() {
16.   delete req;
17.   if (window.XMLHttpRequest) {     // IE7, FF, Opera, ...
18.     req = new XMLHttpRequest();
19.   }
20.   else if (window.ActiveXObject) { // <=IE6
21.     req = new ActiveXObject("Microsoft.XMLHTTP");
22.   }
23.   if(req) {
24.     req.onreadystatechange = processReq;
25.     req.open("GET", URL, true);
26.     req.send(null);
27.     window.setTimeout("Next()", 5000);
28.   } 
29. }
30. window.onload = Next;
31. </script>

After complete data message is ready in browser, data are processed by lines 6-10. First, data row is split to single values (line 7), then in cycle (lines 8, 9, 10) values are inserted in the matching measuring cells. As a data separator character | (pipe) is used here in accordance with how data are prepared on server. To update the value in cell function document.getElementById("d" + (i)) is used to identify regular cell. Property innerHTML is not standardized, but all common browsers understand that. For the sake of simplicity there is no error testing conditions in script.

No parameters are send to server in this example. When server recieves request, it sends back actual data, therefore no parameters are necessary. In case when e.g. historical data are required, some parameter which specifies history would be needed. Then address of server script is appended by query string and URL would look something like getRecord.asp?id=1234. Parameters are notated as pair of values name=value. Each pair is separated by character & and have to be encoded according to the escape sequence. Another way of sending parameters to server is to put them in send method (line 26, in place of null); then parameter "POST" have to be used in line 25.

Server script

It is possible to debug server script independently of browser Javascript Ajax code. Enter address of Ajax server script to the address bar of browser (including eventual parameters), and check source code which is returned. Bellow is data message from this example. Notice that server script does not insert sections html, head, nor body into data message. Only plain text is sent, and individual items of data message are separated by pipe character.

27.3.2007 21:14:30|1351|1446|361.2|721.6

Cache and Code page

One of the Ajax technology problem is browser cache. Browser saves data message received from server in its cache and at next request browser tries to read data from cache, not from server. To use cache data is an advantage when more static content is requested, but when you need to transfer real dynamic data as in this example, cache memory needs to be eliminated. Therefore server script has to set immediate expiration of message.

Another problem is code page. Original or displayed HTML page and Ajax message have to use the same character set, or code page. By default, Ajax uses code page UTF-8. Whenever HTML and Ajax message code pages are not identical, Ajax message may look like in following screenshot.

AJAX: code page error

It is desirable and correct to use code page UTF-8, but not always it is possible or easy. For example when database is used by both web and desktop programs. Text string operations in code UTF-8 are not quite simple.

Because Ajax message does not contain section head, there is no possibility to use meta tags for setting expiration, or for code page. Therefore HTTP header have to be modified. How to modify HTTP header is demonstrated in the following example. Such modification have to be implemented before any HTML code output, and remind of that HTTP header is not visible directly in page source code.

ASP:
<%
Response.AddHeader("Cache-Control", "no-cache")
Response.AddHeader("Content-Type: text/html", "charset=Windows-1250")
%>

PHP:
<?PHP
header("Cache-Control: no-cache");
header("Content-type: text/html; charset=Windows-1250") 
?>

Expiration time for Ajax script can be set directly on server, according to article IIS basic setting too. Another way how to require new data is to append URL with always new, unique parameter. As suitable parameter can be used time stamp (13 digit number indicating count of millisecond since 1970). Following statement should be inserted after line 24 into listing above. URL = "getStatus.asp?t=" + ((new DatelueOf());

Charset setting by the help of HTTP header operates in all standard browsers except Opera, which assumes Ajax data in format UTF-8 only.

Ajax specialities

By help of XMLHttpRequest object operating in browser can be transfered data only from the same server, where original web page is situated, it means data from the same domain. Ajax in browsers today cannot request crossdomain data. That can be done by server only. How at it is described in article Ajax on server.

In browser always asynchronous data transfer is used. Synchronous request would cause stop browser react until answer from server is recieved. Synchronous Ajax request fits for using on server.

If you develop your application on workstation by the help of IIS, be aware of account limit connections to IIS. In practice IIS on workstation can support only two pages at once running Ajax code (one Ajax page are rated as two accounted users).

updated 22.11.2009