Calls to a remote service are asynchronous. After you invoke an asynchronous call, your application does not wait for the result, but continues to execute. Therefore, you typically use events to signal that the service call has completed.
When a service call completes, the WebService and HTTPService components dispatch one of the following events:
You can also handle the invoke event, which is broadcast when an RPC component makes the service call. This event is useful if operations are queued and invoked at a later time.
You can handle these events at three different levels in your application:
Handle events at the component level by using the fault and result properties of the component to specify the event handlers, as the following example shows:
<?xml version="1.0"?>
<!-- ds\rpc\RPCIntroExample.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;
public function handleResult(event:ResultEvent):void {
// Handle result by populating the DataGrid control.
// The operation returns an Array containing product ID, name, and price.
myDG.dataProvider=event.result;
}
public function handleFault(event:FaultEvent):void {
// Handle fault.
Alert.show(event.fault.faultString, "Fault");
}
]]>
</mx:Script>
<!-- Define a WebService component and connect to a service destination. -->
<mx:WebService
id="adbe_news"
useProxy="true"
destination="ws-catalog"
result="handleResult(event);"
fault="handleFault(event);"/>
<!-- Call the getProducts() operation of the web service.
The operation takes no parameters. -->
<mx:Button click="adbe_news.getProducts();"/>
<!-- Define a DataGrid control to diplay the results of the web service. -->
<mx:DataGrid id="myDG" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn dataField="productId" headerText="Product Id"/>
<mx:DataGridColumn dataField="name" headerText="Name"/>
<mx:DataGridColumn dataField="price" headerText="Price"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
In this example, all operations that you invoke through the WebService component use the same event handlers.
For the WebService component, you can handle events at the operation level. These event handlers override any event handler specified at the component level. When you do not specify event listeners for an operation, the events are passed to the component level.
In the following MXML example, the WebService component defines default event handlers, and the operation specifies its own handlers:
<?xml version="1.0"?>
<!-- ds\rpc\RPCResultFaultMXML.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.rpc.soap.SOAPFault;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;
public function getProductsResult(event:ResultEvent):void {
// Handle result.
}
public function getProductsFault(event:FaultEvent):void {
// Handle operation fault.
Alert.show(event.fault.faultString, "Error");
}
public function defaultResult(event:ResultEvent):void {
// Handle result.
}
public function defaultFault(event:FaultEvent):void {
// Handle service fault.
if (event.fault is SOAPFault) {
var fault:SOAPFault=event.fault as SOAPFault;
var faultElement:XML=fault.element;
// You could use E4X to traverse the raw fault element
// returned in the SOAP envelope.
}
Alert.show(event.fault.faultString, "Error");
}
]]>
</mx:Script>
<mx:WebService id="WeatherService"
destination="ws-catalog"
result="defaultResult(event);"
fault="defaultFault(event);">
<mx:operation name="getProducts"
fault="getProductsFault(event);"
result="getProductsResult(event);">
</mx:operation>
</mx:WebService>
<mx:Button click="WeatherService.getProducts.send();"/>
</mx:Application>
Sometimes, an application requires different event handlers for calls to the same service. For example, a service call uses one event handler at application startup, and a different handler for calls during application execution.
To define event handlers for a specific service call, you can use the AsyncToken object returned by the send() method. You then register event handlers on the AsyncToken object, rather than on the component, as the following ActionScript code shows:
<?xml version="1.0"?>
<!-- ds\rpc\RPCAsynchEventHandler.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.rpc.soap.SOAPFault;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;
import mx.rpc.AsyncToken;
import mx.rpc.AsyncResponder;
// Define an instance of the AsyncToken class.
public var serviceToken:AsyncToken;
// Call the service, and then
// assign the event handlers to the AsyncToken object.
public function setCustomHandlers():void {
// send() returns an instance of AsyncToken.
serviceToken = WeatherService.getProducts.send();
var asynchRes:AsyncResponder =
new AsyncResponder(getProductsResult, getProductsFault);
serviceToken.addResponder(asynchRes);
}
// Use the token argument to pass additional information to the handler.
public function getProductsResult(event:ResultEvent, token:Object = null):void {
// Handle result.
}
// Use the token argument to pass additional information to the handler.
public function getProductsFault(event:FaultEvent, token:Object = null):void {
// Handle operation fault.
Alert.show(event.fault.faultString, "Error");
}
public function defaultResult(event:ResultEvent):void {
// Handle result.
}
public function defaultFault(event:FaultEvent):void {
// Handle service fault.
if (event.fault is SOAPFault) {
var fault:SOAPFault=event.fault as SOAPFault;
var faultElement:XML=fault.element;
// You could use E4X to traverse the raw fault element
// returned in the SOAP envelope.
}
Alert.show(event.fault.faultString, "Error");
}
]]>
</mx:Script>
<mx:WebService id="WeatherService"
destination="ws-catalog"
result="defaultResult(event);"
fault="defaultFault(event);">
<mx:operation name="getProducts"/>
</mx:WebService>
<!-- Call the service using the default event handlers. -->
<mx:Button label="Use Default Handlers" click="WeatherService.getProducts.send();"/>
<!-- Call the service using the custom event handlers. -->
<mx:Button label="Use Custom Handlers" click="setCustomHandlers();"/>
</mx:Application>
Notice that some properties are assigned to the token after the call to the remote service is made. In a multi-threaded language, there would be a race condition where the result comes back before the token is assigned. This situation is not a problem in ActionScript because the remote call cannot be initiated until the currently executing code finishes.
Send me an e-mail when comments are added to this page | Comment Report
Current page: http://livedocs.adobe.com/blazeds/1/blazeds_devguide/rpc_httpws_08.html