SPIN Project Blog

Diary of a diploma thesis at the Institute for Informatics at the University of Munich, Germany.

Monday, August 21, 2006

Using AJAX for simulating proactive spoken dialogue

As I have written in my last post I am currently experimenting with AJAX for VoiceXML. Today, I finished my first spike on that topic and I think it is worth sharing.

My idea was to use AJAX to asynchronously 'push' updated data from the server to the client in order to prompt the user with it, i.e. doing pretty much the same thing a web developer would do for the visual web when 'pushing' data from the server to the web browser. AJAX has all the nice features in place to realize the client-server communication and since XHTML+Voice lets us call VoiceXML prompts from within JavaScript code we can integrate AJAX with VoiceXML in a straight forward way:

Step One: Remembering the Last Server Response

In the head of our XHTML document we will define the following JavaScript code. Our global variable ajax_response will be used to contain the most current response from the remote server. old_ajax_response will save a previous copy of ajax_response that will be used to see if the content delivered by the server has changed. Some words on this later.
var ajax_response = '';
var old_ajax_response = '';
Next, we will provide a simple getter for ajax_response:
function getPrompt(){
return ajax_response;
}

Step Two: The VoiceXML Output Form

Since we are interested in presenting the updated server data to the user, we will use a simple VoiceXML form containing a simple prompt:
<form xmlns="http://www.w3.org/2001/vxml" id="myPrompt">
<block>I have just received an update for you
<value expr="getPrompt();">
</value>
</block>
</form>
The form simply asks the getPrompt() method for the latest data that has been received from the server and uses it to prompt the user.

Step Three: Simulating Server Push


Next, we need a method for making a request to our remote JSP script that is generating the server-side content.
function makeRequest() {

var url = 'my_ajax_example.jsp';
var http_request = false;

if (window.XMLHttpRequest) { // Mozilla, Safari, ...
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}

if (!http_request) {
alert('Giving up :( Cannot create an XMLHTTP instance');
return false;
}
http_request.onreadystatechange = function() { myHandler(http_request); };
http_request.open('GET', url, true);
http_request.send(null);

}
The last function we need is the myHandler callback function that has been used in the above AJAX call. This simple method has the real magic in it. When the data that arrives from the server is new to the client, it uses the DOMActivate event to activate the myPrompt form.
function myHandler(http_request) {

if (http_request.readyState == 4) {
if (http_request.status == 200) {
ajax_response = http_request.responseText;

if (old_ajax_response != ajax_response) {
old_ajax_response = ajax_response;

var e = document.createEvent("UIEvents");
e.initEvent("DOMActivate","true","true");
document.getElementById('myPrompt').dispatchEvent(e);

}

} else {
ajax_response = 'There was a problem with the request.';
}
}
}
Step Four: Initializing the Polling Procedure

Now we have almost everything we need: We have the JavaScript in place that asks the server for an update, we know how to include this data in a VoiceXML form and now all that's left is telling the browser to poll the server for an update using an interval of our choice. We need to do this, because we are just simulating server push. Our client still needs to poll the server in order to receive updated data. This is done by adding the following line of JavaScript code to the above JS code, which is going to call the makeRequest method every ten seconds:
var theTimer = setInterval("makeRequest()", 10000);
Conclusion

The presented example shows how AJAX can be used to simulate a server push voice dialogue to the user. It is a proof-of-concept, nothing more. If you are going to use this for your applications you should make sure to only send as much data to the client as necessary. The example always loads a complete data fragment and compares it to the last one received. This is not network efficient, though. Incremental updates might be a better idea for your application.

Acknowledgement

This example is based on AJAX code snippets from an introductory article by great people at Mozilla (code used under MIT License). DOMActivate for use in VoiceXML forms is described in section 4.2.1 of the XHTML+Voice Profile 1.2 note at VoiceXML.org.

0 Comments:

Post a Comment

<< Home