DOAP - Remote Abstract Data Access Protocol by Dave

<< ErrorsContentsAdditional Topics >>

Synchronous Requests

Requests from a web client to a server using XMLHTTP can be synchronous or non-synchronous.

A synchronous (or asynchronous) request happens in the background while other code or events continue to happen. A non-synchronous request holds everything up while it executes until the result is returned. In network client/server terms this is like the difference between a non-blocking and blocking socket.

DOAP supports both methods of making requests. By default it is non-synchronous.

Although synchronous requests are "nicer" to the user they always have the possibility of unexpected changes occurring or another event being called while they are executing (maybe even the same request object bring used again resulting in a race condition).

The majority of AJAX enabled applications use synchronous requests but then have to take special care to avoid further user input or changes by disabling input fields or covering the entire window in a translucent DIV.

For this reason I strongly suggest you consider the need for a synchronous request being using that method. If you require a background process (for example an automated update of a dashboard item) or similar then a synchronous request may be best to allow the rest of your application to continue running. If however you need to fetch the data and can't do anything until it has arrived then a non-synchronous request may be best.

Of course you can always update something on your page to indicate the system is "working" then call the non-synchronous request and clear the message when it returns. This notifies the user and avoids any confusion if the request may take a while.

Using Synchronous Requests

To use a synchronous request you need to set the DOAP.async property to true and provide a function to DOAP.callback as your callback/handler function. This function will be called when data is returned.

Please note that in testing the async function was not found to operate correctly in IE<=6

Example

The following example shows synchronous and non-synchronous requests. There is a bar of continuous activity on the screen which demonstrates the difference in terms of continuing script execution (click here to see it run). Note the server-side script has a 2 second delay to allow the effects to be clearly shown (it's not normally that slow!).

Server-Side DOAP Server PHP
<?php
ob_start(); // ensure no messy output from includes
 
// Our function that returns the datetime string
function get_time()
{
	sleep(2); // sleep 2 seconds so the difference can clearly be seen
	return date("Y-m-d H:i:s");
}
 
 
require("xmlcreate.inc.php"); // include the xmlCreate library
require("doap.inc.php"); // include the DOAP Server library
 
$doap = new DOAP_Server(); // create a DOAP Server object
 
// Register get_time with 0 parameters
$doap->Register("get_time",0,0);
 
ob_clean(); // clean any messy output from includes
 
$doap->Process(); // get DOAP Server to process the request
?>

The server code just defines a function returning a formatted datetime string after a two second pause to demonstrate the effect.

Client-Side DOAP Server HTML/JavaScript
<HTML>
<HEAD>
<TITLE>DOAP Example 5: Asynchronous Requests</TITLE>
<!-- Include the DOAP Client JavaScript -->
<SCRIPT TYPE="text/javascript" SRC="doap.js"></SCRIPT>
 
<SCRIPT TYPE="text/javascript">
var doap = new DOAP(); // create the DOAP Client object
doap.url = "example5.php"; // set the DOAP Server URL
 
function my_callback( data ) // callback for async request
{
	document.getElementById('results').innerHTML = data;
}
 
function async_request() // make an asynchronous request to the server
{
	document.getElementById('results').innerHTML = "Working...";
	try
	{
		doap.async = true; // set DOAP to use async request
		doap.callback = my_callback; // set callback function to my_callback
		doap.call('get_time'); // call get_time() on server
	}
	catch(e) // catch any errors
	{
		// deal with any errors if it's a DOAP error or any other type of exception
		if(e instanceof DOAP_Error) alert("DOAP Error "+e.code+": "+e.desc);
		else alert("Unknown Error: "+e);
		return; // and exit the function if an error was encountered
	}
	// output is dealt with by my_callback
}
 
function nonsync_request() // make a non-synchronous request to the server
{
	document.getElementById('results').innerHTML = "Working...";
	try
	{
		doap.async = false; // set DOAP to use non-sync request
		var result = doap.call('get_time'); // call get_time() on server
	}
	catch(e) // catch any errors
	{
		// deal with any errors if it's a DOAP error or any other type of exception
		if(e instanceof DOAP_Error) alert("DOAP Error "+e.code+": "+e.desc);
		else alert("Unknown Error: "+e);
		return; // and exit the function if an error was encountered
	}
	// if we get here output the result
	document.getElementById('results').innerHTML = result;
}
 
var action_ctr = 0;
function constant_action() // this just shows some ongoing constant action
{
	var activity="<PRE>[";
	for (var i=0; i<30; i++)
	{
		if (i<action_ctr) activity+="_";
		else if (i>action_ctr) activity+="-";
		else activity+="|";
	}
	activity+="] "+action_ctr+"</PRE>";
	document.getElementById('activity').innerHTML = activity;
 
	action_ctr++;
	if (action_ctr>29) action_ctr=0;
}
setInterval("constant_action()",100);
</SCRIPT>
</HEAD>
 
<BODY>
<DIV ID="results" CLASS="result_div">Results will appear here BY MAGIC!</DIV>
<BR /><BR />
<DIV ID="activity">Show Constant Activity Here...</DIV>
<BR /><BR />
 
<!-- The links to call the requests -->
<A HREF="#" onClick="nonsync_request();">Make a non-synchronous request to server</A><BR /><BR />
<A HREF="#" onClick="async_request();">Make an asynchronous request to server</A><BR /><BR />
 
<!-- And a link to clean the results div back if needed -->
<A HREF="#" onClick="document.getElementById('results').innerHTML='<BR />';">Clear Results DIV</A>
 
</HTML>
 

The client code defines two functions, one for a synchronous and the other for non-synchronous requests and puts links on the page to call them. There is also a function to continually update a text animation so you can see when execution is stopped.

<< ErrorsContentsAdditional Topics >>