4.2 Using NetServices

In the examples in the preceding chapters, the NetServices.as file was included to allow you to use two methods of the NetServices class: createGatewayConnection( ) and setDefaultGateway( ).

There is also a NetServices.getVersion( ) method, which returns the current version of the NetServices class. You can check the version number to maintain backward compatibility if future versions of the NetServices class contain new functionality. Several other methods are used internally as well.

The NetServices class also gives you an interface to the NetConnection class and enhances the NetConnection class to include several new methods:

  • getService(remoteMethod, responderObject[, arg1, arg2,...])

  • setCredentials(username, password )

  • RequestPersistentHeader( )

  • ReplaceGatewayUrl(url )

The first two methods should be accessed through the connection that you set up with the createGatewayConnection( ) method. The last two methods are reserved for future use by the Flash Remoting gateway.

4.2.1 Establishing the Gateway Connection

Calling the NetServices.createGatewayConnection( ) method initializes a NetConnection object and returns that object to the Flash movie. The new NetConnection object can be used to connect to the Flash Remoting gateway on the server.

Here, a hardcoded URL for the gateway is passed as an argument to createGatewayConnection( ):

var myURL = "http://localhost/flashservices/gateway";
var myConnection_conn = NetServices.createGatewayConnection(myURL);

Alternatively, the URL can be defined with another method, NetServices.setDefaultGateway( ). The NetServices.setDefaultGateway( ) method provides a way to hardcode a default gateway URL within your Flash movie while retaining the flexibility to pass a gateway URL to the movie from the HTML page. When you use setDefaultGateway( ) to specify the URL, the URL is stored as a property of the NetConnection object. When the createGatewayConnection( ) method is called, the NetConnection object determines the gateway URL as follows:

  1. If the Flash developer included a URL in the call to createGatewayConnection( ), as in Example 1-1, that URL is used.

  2. Otherwise, the NetConnection object checks whether the HTML page request is an HTTP or HTTPS request. If so, it uses the URL specified by the gatewayURL variable within the FlashVars attribute of the <OBJECT> or <EMBED> tag.

  3. If the URL is still not found, the NetConnection object uses the gateway URL specified in the earlier call to setDefaultGateway( ) method, if any.

  4. If no URL is found, an error message is sent back to the Flash movie and displayed in the Output window (in authoring mode only). In a production environment, the attempt to create the gateway connection fails silently.

For the purposes of demonstration, I have hardcoded the Flash Remoting gateway's URL path in previous examples. Passing the URL into the movie as a variable from HTML makes it easier to move your Flash Remoting application to a different server without having to recompile the .swf file.

To change the URL at runtime, add a FlashVars attribute to the <OBJECT> and <EMBED> tags of the HTML page containing the Flash movie. FlashVars, first supported in Flash Player 6, allows you to pass name/value pairs from the HTML page to the Flash movie. The HTML for a typical Flash movie might look like this, with the FlashVars attributes in bold:

<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 
 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/
 swflash.cab#version=6,0,0,0" WIDTH="550" HEIGHT="400" 
 id="mymovie" ALIGN="">
 <PARAM NAME=movie VALUE="mymovie.swf">
 <PARAM NAME=FlashVars 
  VALUE="gatewayURL=http://www.flash-remoting.com/flashservices/gateway">
 <PARAM NAME=quality VALUE=high>
 <PARAM NAME=bgcolor VALUE=#FFFFFF> 
 <EMBED src="mymovie.swf" quality=high bgcolor=#FFFFFF  WIDTH="550" 
  HEIGHT="400" NAME="Untitled-2" ALIGN=""
  TYPE="application/x-shockwave-flash"
  FlashVars="gatewayURL=http://www.flash-remoting.com/flashservices/gateway"
  PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer">
 </EMBED>
</OBJECT>

The FlashVars attribute should specify the variable name gatewayURL and give it a value that is the path to the Flash Remoting gateway on your server, because gatewayURL is the variable that the NetConnection object is expecting:

gatewayURL=http://www.flash-remoting.com/flashservices/gateway

The best scenario is to use a setDefaultGateway( ) method to create a default URL in the ActionScript code, but then override that within your final web page using a gatewayURL variable within the FlashVars attribute. This gives you the flexibility to test your movie in authoring mode and change the URL when publishing the movie to the Web:

// Create the connection and service objects
NetServices.setDefaultGatewayURL("http://localhost/flashservices/gateway");
var myConnection_conn = NetServices.createGatewayConnection( );

After executing the preceding code, the variable myConnection_conn contains an instance of the NetConnection class. Notice that there is no need to parse the gatewayURL variable from the HTML page; this is done automatically behind the scenes by the NetConnection object.

If you examine the NetServices.as file, you can see the last few lines of code in the definition for the createGatewayConnection( ) method:

NetServices.createGatewayConnection = function (url) {
  //... snipped code ...
  var nc = new NetConnection( );
  nc.connect(url);
  return nc;
};

You can see that it creates a new NetConnection object and uses the connect( ) method to create a connection before returning the object to the caller. The method is named connect( ), but the actual connection to the remote server isn't made until making a call to the remote service.

4.2.2 Creating the Service Object

When you set up a connection using createGatewayConnection( ), the resulting NetConnection object can be used to gain access to a service by calling its getService( ) method as shown here:

var myService = myConnection_conn.getService("com.oreilly.frdg.HelloUser", this);

The last parameter passed to getService( )?in this case, the current object this?is sometimes called a default responder object. This object will handler future results returned in response to remote calls on the service. See Section 4.3 later in this chapter for many more details on responder objects.

The service object returned by getService( ) is used to invoke methods or functions of the remote service. Although the way in which you access methods of a service is similar for most server models, details for each server-side platform are covered in Chapter 5 through Chapter 9.

Calling getService( ) also automatically sets up a NetServiceProxy object and the NetServiceProxyResponder object. You shouldn't have to deal with these directly, as they are used behind the scenes, but they are explained next.

4.2.2.1 NetServiceProxy

For each service established via getService( ), Flash automatically generates an object of the NetServiceProxy class to pass the remote call to the server and handle the results from the remote call as well. It makes sure that the AMF packets to and from the remote service are deserialized and registered properly as ActionScript objects. See Section 4.7 later in this chapter for more information.

When you connect to a remote service with a getService( ) call like this:

var myService = myConnection_conn.getService("com.oreilly.frdg.HelloUser", this);

getService( ) returns an instance of the NetServiceProxy class. The NetServiceProxy object acts as a proxy or middleman to the remote service and initiates the call to methods of the remote service.

4.2.2.2 NetServiceProxyResponder

For each service established via getService( ), Flash also automatically generates an object of the NetServiceProxyResponder class. The NetServiceProxyResponder object dispatches onResult events containing the response from a remote method call, as described under Section 4.3. Similarly, the NetServiceProxyResponder object also dispatches onStatus events if an error occurs when invoking a method of a remote service. Again, see Section 4.3 for many important details on the order in which NetServiceProxyResponder searches for the callback functions to handle onResult and onStatus events.

4.2.3 User Authentication

Authenticating a user is a tedious but necessary task eventually faced by every application programmer. Although different application servers have different methods of authenticating users, the NetConnection.setCredentials( ) method provides a standard way to send authentication information to your server-side application. At the time of this writing, setCredentials( ) is supported by ColdFusion MX and JRun 4 only.

The setCredentials( ) method sends a credentials header with userid and password name/value pairs to the remote server. The server, in turn, must be equipped to handle the header. The setCredentials( ) method is covered at length in Chapter 5 and Chapter 7.

4.2.4 Using the NetConnection Object Directly

Flash Remoting includes a NetConnection class as part of its core classes. The NetServices class simply provides a higher-level interface to the NetConnection class. The NetServices.as file contains the classes used by Flash Remoting to communicate with the server. You don't have to include the NetServices.as file if you use the NetConnection class directly. That is, the classes contained in the NetServices.as file are not required, but they are easier to use than native NetConnection methods. However, let's look at the NetConnection methods for comparison.

To utilize the NetConnection class directly you can first create a connection object:

var myConn = new NetConnection( );

Then connect to the Flash Remoting gateway using the NetConnection.connect( ) method:

myConn.connect("http://127.0.0.1/flashservices/gateway");

To call a method of a remote service, you can use the NetConnection.call( ) method, specifying the service and method names together in one argument, the responder object as the next argument, followed by any arguments to send to the remote method. In this case, there are no arguments supplied to the remote method:

myResult = new Object( );
myConn.call("com.oreilly.frdg.HelloWorld.sayHello", myResult);

Notice that you must specify the complete namespace of the service (com.oreilly.frdg.HelloWorld), along with the method name without parenthesis (sayHello) in the call to the server. The Flash Remoting gateway treats this call the same as invoking a method on the service object returned by getService( ), as shown in Example 1-1, portions of which are reproduced here:

#include "NetServices.as"
// Set the URL for the gateway connection
var myURL = "http://localhost/flashservices/gateway";
// Specify the path to the service
var myServicePath = "com.oreilly.frdg.HelloWorld";
// Create a responder object (event handlers are not shown)
myResult = new Object( );
// Establish the gateway connection
var myServer = NetServices.createGatewayConnection(myURL);
// Access the remote service
var myService = myServer.getService(myServicePath, myResult);
// Invoke a remote method on the service
myService.sayHello( );

One or more arguments can be specified following the service and method names and the responder object. For example, you can call the HelloUser service from Chapter 2 and pass it a username as follows:

myConn.call("com.oreilly.frdg.HelloUser.sayHello", myResult, username_txt.text);

Again, the Flash Remoting gateway treats this call the same as using the NetServices class, as shown in Example 2-1.

Although our brief examples of using NetConnection directly don't include callback handlers to handle the results or status errors, you can set up event handlers in the manner shown in Examples Example 1-1 and Example 2-1. You can't, however, use named callback functions, such as methodName_Result (as shown in Example 3-8) without the NetServices class.

Although the NetConnection object can be used directly, the NetServices class provides several advantages:

  • The service object can be created once (using getService( )) and methods can be invoked on that service by name, which is more intuitive.

  • You can specify result-handling functions using the methodname_Result naming convention.

  • The NetServiceProxy object created automatically by getService( ) acts as a proxy to handle any necessary deserialization of the results into ActionScript objects.

  • Connection URLs can be set up using a setDefaultGatewayUrl( ) method and then overridden by the parameters coming from HTML sent to the movie.

If you choose to call the NetConnection methods directly, the NetConnection.close( ) method can be used to close a connection to the Flash Remoting gateway:

myConnection_conn.close( );

Furthermore, the NetConnection.addHeader( ) method allows you to attach a header to the AMF packet sent to the server, as follows:

myConnection_conn.addHeader(name, mustUnderstand, object)

The name argument is a header name that you specify (such as credentials). The second argument, mustUnderstand, is a Boolean value; if it is true, the server must process the header before any further processing can take place. It is up to your server-side code to process the header. The third argument can be any ActionScript object. A typical call to addHeader( ) is included in the NetServices.as file, which you can examine by looking at the source file in the Flash Include folder. The NetConnection.setCredentials( ) method, covered in Chapter 5, uses addHeader( ) to process the login information in a Flash movie.

4.2.4.1 NetConnection debugging methods

The NetConnection class also has several methods that you can use to debug your Flash Remoting application:

  • NetConnection.getDebugConfig( )

  • NetConnection.getDebugID( )

  • NetConnection.setDebugID( )

  • NetConnection.trace( )

These methods are covered in Chapter 13, where we talk about debugging. They are also documented in Chapter 15.



    Part III: Advanced Flash Remoting