I never really had the chance to use Flash Remoting on a commercial project and it has been years since I played around with it. It must have been 2003/2004 or so that I first tried using it. At the time I tried it with ColdFusion, which worked pretty OK, and with Java (JRun to be precise). I was pretty impressed with the level of abstraction that Flash Remoting provided. Not just from the ActionScript point of view but also from the server point of view. No more manual parsing of data structures. Great! Thinking about it, I can’t really understand why it isn’t more widely used. It seems that it is only used on the more corporate websites, or very specialized stuff to say the least, and you don’t see it much used with the ‘typical’ Flash stuff or hear much about it in the general Flash community. Maybe that’s because Flash Remoting is quite a techy thing to get your head around and that it’s out of the league of your typical Flashers. Maybe BlazeDS is going to make a change to this, but somehow I doubt that.
Anyways, I was playing with AMFPHP over the weekend. It was a fair bit of work to get it all up and running. The documentation on the site isn’t what you would call ‘good’ but after a bit of puzzling I was able to figure it out and was able to make a request through Remoting and get a result value back. Awesome. The next thing I wanted to do was to use a bare bone NetConnection instance to connect to AMFPHP. After all, in Flash it’s the only intrinsic object available to connect to an AMF server and somehow the Remoting classes provided by Adobe seem to be so incredibly complicated and not intuitive to use at all. Luckily they changed this for ActionScript 3, but I wanted to figure this out for ActionScript 2.
The first mistake I made was to focus on the connect method of the NetConnection object. I figured out that the NetConnection has an undocumented onStatus event handler. I figured also out that when I made a connection the onStatus wasn’t triggered when I used http, only when I used rtmp. Hmmm, that was kinda odd. I played around with it for a while and decided to move on to the next thing, which was calling a remote method. I created a simple HelloWorld method on the AMFPHP server and called it using the Remoting classes provided by Adobe. That worked fine. So I set up the following code using a bare bone NetConnection:
var responder : Object;
responder = new Object();
responder.onResult = function( result : String ) : Void
{
trace("responder:onResult " + result);
};
responder.onStatus = function( info : Object ) : Void
{
trace("responder:onStatus " + info.code + ", " + info.level);
};
var nc : NetConnection;
nc = new NetConnection();
nc.onStatus = function( info : Object ) : Void
{
trace("nc:onStatus " + info.code + ", " + info.level);
};
nc.connect("http://localhost/remoting/gateway.php");
nc.call("HelloWorld.say", responder);
Now, this is where I went on my next wild goose chase. I spent the next couple of hours trying to figure out why this didn’t work. Going back and forth between the test case I did with the Adobe classes and this example. I just couldn’t figure out why the NetConnection example wasn’t working. I made dozens of small changes, trying to isolate the problem. But alas. Nothing. Until, at one point, I decided to change this line:
nc.call("HelloWorld.say", responder);
To this:
nc.call("HelloWorld.say", responder, "hello");
Bang! It worked. Apparently, just because the signature didn’t match previously with any remote function on the server, the function simply wasn’t called… Maybe it’s my naivety, but I was expecting the parameter to be just passed as an empty string, or null, if not specified. I’m currently not sure where the problem lies with that, but I guess it’s with AMFPHP. I think AMFPHP is to strict on signature testing and should be a bit more relaxed when it comes to that. I played around with it a bit more and decided to call it a day.
Today, while doing the dishes, or better, cleaning out the dishwasher the http/rtmp problem just solved itself. Of course the behavior was different! When connecting to an AMF server through http, the connection is stateless and can’t be maintained. In fact, calling the connect method on the NetConnection object doesn’t actually do that much and behaves completely different than with rtmp. It does call the server, but it seems to only check if the location, or gateway you want to call, exists. Only over an rtmp connection the Flash Player can maintain an open connection with the server. Duh!
I will definitely be using more Flash Remoting in the future and will most likely try to push it for more commercial projects from now on. It’s a great technology, saves heaps of bandwidth and no more XML/JSON parsing!