We worked on an example demonstrating XML Web Services integration for AJAX clients. The complete example can be found at:
http://dev.flashorb.com/weborb/examples/googleonsteroids.htmUPDATE:
although this blog entry covers some of the details of the implementation, there is a thorough review of the example available here:
The client side of the example is as basic as the Google's main interface, i.e. all it has is a search query text field. The text field is sensitive to the user's input. As soon as the user stops typing, the client sends the query to Google and displays the result. WebORB sits between the client application and Google web service and brokers the request. There are several reasons why WebORB would have to be in the picture:
- Some browsers do now allow direct connections to 3rd party hosts. Requests can be sent only to the server where the page is loaded from
- The example uses the license key we got from Google and also lets the user enter his key. Since we cannot expose our license key, we have to hide it in our server side class
The server side implementation is very simple. We used VS.NET to create a web reference for the Google service. The code instantiates web service proxy and invokes the search query method:
using System;
using googlesearch.com.google.api;
namespace googlesearch
{
public class GoogleSearch
{
public GoogleSearchResult runGoogleSearch( string query,
string googleKey )
{
if( googleKey == null )
googleKey = "********* our google key goes here **********";
// instantiate google web service proxy
GoogleSearchService service = new GoogleSearchService();
// invoke web service method
GoogleSearchResult searchResult = service.doGoogleSearch(
googleKey, query,
0, 10, false, "", false, "", "", "" );
// return result 'as is' to the client.
// let WebORB serialize it so the data structure
//looks the same in JS
return searchResult;
}
}
}
The client side script is just as simple. When the page loads, the script binds to the server side object:
<body onload=bind()>function bind()
{
// hide the animation - need to show it only when a query
// is in progress
document.getElementById("animation").style.visibility = "hidden";
// build a proxy to the backend object
if( googleProxy == null )
googleProxy = webORB.bind( "googlesearch.GoogleSearch",
"weborb.aspx" );
requestStack = new Array();
}
When the conditions for issuing a query are met (user pauses or enters space or hits Enter), the script executes the following function:
function search()
{
// get what the user typed in
var search = document.getElementById( "searchtext" ).value;
// if the user provided his own key, use in the invocation
var googleKey = document.getElementById( "gkey" ).value;
// mark the request in the stack - to avoid overlap
//of multiple responses
requestStack.push( search );
// turn on animation notifying the user of the query in progress
document.getElementById( "animation" ).style.visibility = "visible";
// run the query on the backend object (see the code above)
var async = new Async( processSearchResults, processError )
googleProxy.runGoogleSearch( search,
googleKey.length != 0 ? googleKey : null,
async );
}
The client code invokes the remote method asynchronously - see the Async argument. The argument contains two callbacks - one for successful result and the other is for any errors returned from the invocation. See the source for the implementation of
processSearchResults and
processError.
Something to note about the processSearchResults is the response value maintains full fidelity with the original endpoint. As a result, the data can be accessed as:
function processSearchResults ( result )
{
[skip]
for( var i = 0; i < result.resultElements.length; i++ )
{
searchContent += result.resultElements[ i ].title;
if( result.resultElements[ i ].snippet )
searchContent += result.resultElements[ i ].snippet;
searchContent += result.resultElements[ i ].URL;
}
[skip]
searchResults.innerHTML = searchContent;
}