10,000 foot view of Remoting

Remoting can be a bit difficult to use at first, however it becomes very natural and simple after you've used it a few times.

When starting a Remoting project in Flash, start by opening Help > Common Libraries > Remoting and drop the RemotingClasses and RemotingDebugClasses onto the stage. A second step is to start the NetConnection debugger by inserting the following code in the first frame of your movie or in your main classes' init function:

import mx.remoting.debug.NetDebug;
import mx.remoting.*;
import mx.rpc.*;
NetDebug.initialize();

Use these sets of imports on every new frame or class you use which depends on Remoting, otherwise Flash will tell you it can't find the classes when you try to compile.

The next step is to create the service. The service constructor has 5 arguments, however for most practical purposes you will only want to specify the first three, the first being the location of the gateway, the second usually null, and the third the location of the service:

var service:Service = new Service('http://localhost/amfphp/gateway.php', null, 'com.company.MyService');

This will connect to your gateway and look for the com/company/MyService.php file in the services folder. That file must have a class called MyService defined with a methodTable member (details are in the following section).

You can reuse the same service to call different methods. In fact a lot of people like to put their service in a class and access it as a static variable or a singleton. This is the purpose of the ServiceLocator in the ARP framework for example.

Once the Service is created it's time to call a remote method:

var pc:PendingCall = service.myMethod("arg1", {x:'myX'});
pc.responder:RelayResponder = new RelayResponder(this, "onSuccess", "onFault");

To call a method, you first call it as though it was a local service and you will receive a pending call. On the remote server, the myMethod method in the MyService class will be called, if it is defined as a remote function in the methodTable (again, details on next page).

Then you set up the callbacks using a RelayResponder The remote method will actually be called on the next frame. onSuccess will be called in the 'this' scope if the method works, and onFault if not. onFault cannot catch timeouts, missing gateway or fatal errors (NetConnection.Call.BadVersion), only logical errors triggered by the programmer through exceptions (PHP5) or trigger_error (PHP4, and then only E_USER_ERROR and less critical errors will be reported).

There are alternatives available however to RelayResponder. The Relay class works like RelayResponder but using references instead of strings, meaning if you mistype the callback names you will get a compiler error (a good thing).

Now you need to setup the responders:

function onSuccess(re:ResultEvent)
{
    trace("Success!");
    NetDebug.trace(re.result);
}


function onFault()
{
    trace("Fudge! :(");
}

The result of the return in case of a success is inside {firstParameter}.result. Thus get used to re.result. The result will be in a native Flash format (string, number, array, object, etc.).

mx.remoting.RecordSet

So far you've seen how to call remote methods and receive the resulting data. By now you know that it's ridiculously simple to call a remote method with complex arguments using Remoting. However, the most interesting feature of Remoting is its handling of recordsets.

If you sent back a recordset from your remote method (return mysql_query("SELECT * FROM myTable");), the result will be an instance of mx.remoting.RecordSet. This is a special wrapper class that has a ton of nice, useful methods, among them:

  • getItemAt(index) and removeItemAt(index)
  • filtering by a custom function (filter method)
  • sorting with a custom function (sort method)
  • event dispatching

If that's not enough, MM's v2 components are meant to use Recordsets as dataProviders out of the box. For example if you have a datagrid on stage, if you set it's dataProvider to your result, it will show the headers and columns and rows, allow sorting on different columns and whatnot. That's a lot of functionality for a single line of code. Putting it all together:

import mx.remoting.debug.NetDebug;
import mx.remoting.*;
import mx.rpc.*;
NetDebug.initialize();

var service:Service = new Service('http://localhost/amfphp/gateway.php', null, 'com.company.MyService'); var pc:PendingCall = service.myService("arg1", {x:'myX'}); pc.responder:RelayResponder = new RelayResponder(this, "onSuccess", "onFault"); function onSuccess(re:ResultEvent) { var rs:RecordSet = RecordSet(re.result); myDatagrid.dataProvider = rs; } function onFault() { trace("Fudge! :("); }

Remoting has a lot of other features also like authentication and web service consumption but you can immediately see that with just the preceding you can implement tons of functionality much more naturally than with LoadVars and XML.


amfphp.org | Disclaimer | Conditions of use