Flash Remoting

Posted by Luke | Actionscript, Actionscript 2.0, Flash, PHP, Programming, Remoting | Monday 21 July 2008 9:57 pm

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!

(more) ActionScript 3 weirdness

Posted by Luke | Actionscript, Actionscript 3.0, Dribble, Programming | Wednesday 7 May 2008 11:08 am

The other day I was attending the Colin Moock lecture “AS3 from the ground up” here in Sydney. Even though the lecture was very (and I mean very) basic, as it was intended, it was still quite interesting to see the man in action. I sat through the whole thing even though around 4 o’clock I was ready to walk out (of boredom). I’m glad I made it till the end.

Even though the lecture was quite basic there was one thing he pointed out that caught my attention. The implicit calling of the super class constructor. He’s stated that even if you do not specify a call to super in your sub class constructor, the super class constructor is still called. this sounded all to weird for me. I didn’t wanted to shout this out in case I was wrong and I didn’t bring a laptop to test out if this weird behavior was true. And thinking again, AS3 has a number of weird things going on that are not consistent with what you would expect. So, this might be another one of those things.

Never the less, the next day I decided to test this behavior just to make sure this was the case, and behold. It is. Besides the fact that you can’t make constructors private in AS3 (which is a different discussion all together) the super class constructor IS ALWAYS CALLED!!!

As a programmer, for me to override the constructor has actual meaning. It means that I DO NOT WANT THE SUPER CLASS CONSTRUCTOR TO EXECUTE, unless I call the super class constructor explicitly with the super keyword. To me this is another typical one of those; “we complier designers need to protect those poor little programmers from them selfs, the poor souls don’t know what they’re doing” type of thing. Sigh…

For some reason, the more I do with AS3 the the more frustrating it is becoming. Every time I run into small but irritating issues like this the more I tend to step away from the language. Don’t get me wrong, I like the executing speed increase and the improvement from AS2 its just these little annoying things that get to me.

Papervision3D, Quake Models & Color Palettes

Posted by Luke | Actionscript, Actionscript 3.0, Papervision3D, Programming | Tuesday 20 November 2007 3:23 pm

Last week I was working on a port of a Quake model viewer I did in OpenGL to ActionScript 3.0 and Papervision3D. The actual AS3 code is reading the Quake model information from the original binary Quake .mdl file and contains, besides the polygon data, the bitmap that represents the texture for the model. The problem is that Quake uses a global color palette because the game was programmed for 256 colors (remember, this game is from 1996!). None of the models or textures actually stores a palette because they are assumed to all use the same palette and why store it many times… The actual color palette is stored in a separate binary file of 768 bytes in size (256 * 3 = 768, the 3 is for the three r, g, b color channels and every component ranges from the standard 0 – 255).

When building the AS3 version of the Quake model viewer I could have chosen to read the color palette from the binary file by loading it in at runtime. Instead I chose another approach. I created a class that represented the color palette and I embedded the raw palette information as a resource in the swf itself:

package
{
   import flash.utils.ByteArray;

   public class QuakePalette
   {
      [Embed(source="quake.pal", mimeType="application/octet-stream")]
      private static const Palette : Class;

      public var r : Array = null;
      public var g : Array = null;
      public var b : Array = null;

      public function QuakePalette()
      {
         var i : int;
         var a : ByteArray;

         a = new Palette() as ByteArray;

         r = new Array();
         g = new Array();
         b = new Array();

         for( i = 0; i < 256; i++)
         {
            r[i] = a.readUnsignedByte();
            g[i] = a.readUnsignedByte();
            b[i] = a.readUnsignedByte();
         }
      }
   }
}

Above is the code for the actual QuakePalette class that is used by the AS3 Quake model viewer. As you can see, the color palette is embedded inside the class as a resource. By setting the mimeType property to "application/octet-stream" the data is actually embedded as raw binary data. In the constructor the Palette class (the alias by which the raw binary data is known inside the class) is then casted as a ByteArray to be able to access the data. In the end the QuakePalette class has three public properties, r, g & b, that represent the three RGB color channels for easy access.

ActionScript trace

Posted by Luke | Actionscript, Flash, Programming | Friday 12 October 2007 3:16 pm

On my workstation, where I do Flash development, I always run a debugger version of the Flash Player. This is because I do not use the Flash IDE nor Flex Builder for development and I still want to see trace output.

A side effect of having the debugger version of the Flash Player installed is that I also see trace output from any other website with Flash content that I visit when I have the trace console open. Sometimes this is quite funny because some programmers think its really cool to have swear words in their trace output. Most of the time however, I can’t seem to understand or make sense of their output or why its still there in the first place. Maybe I’m just anal, but I always seem to remove any trace statement I put in my code because that trace statement is there for debugging purposes only, not for general logging. Other then that, over the years I’ve adopted a specific syntax when it comes to trace output.

The main problem with trace statements is to be able to find them back in the code where they occurred. If you have a whole bunch of trace statements and your application is quite biggish, then five minutes after putting in the trace you’re probably still be able to remember where you placed it in your code. The next day however, you see a trace statement pop up but you have no clue where in your code the trace statement occurred. “Ah, then you just use the find function on your text editor”, you’d say. Valid point and sometimes this works. But what if your output is composed in the style of:

trace("varname=" + varname + ", somecounter=" + i );

Happy finding!

When I put trace statements in my code I usually include the class and method name in the trace statement. This way I can always quickly locate where in my code the trace statement occurred. My trace statements therefore look something like this:

trace("classname:methodname varname=" + varname + ", somecounter=" + i );

Now, whenever I see a trace statement popping up I know exactly where in my code this occurred and I can locate it in an instance.