AS3 decompiler

Posted on Sunday 7 January 2007

These two blog posts in French passed under the radar, so I am translating and posting them here. Basically, the Tamarin tools include an actionscript byte code (abc) decompiler, which can generate readable pseudocode from swf or abc files. This pseudocode could then be processed to generate actual AS3 code. Awesome, indeed.

Here is what follows. The first part explains how to build the compiler yourself. The second part lets you download the built compiler directly. The last part are my personal comments.

Creating executables with the Tamarin projects

Tamarin can be downloaded from CVS, as outlined by Zwetan. The cvs info is:

cvs -d :pserver:anonymous:anonymous@cvs-mirror.mozilla.org:/cvsroot co mozilla/js/tamarin

Follow the instructions in readme.txt. The project can be compiled under the Microsoft C compiler; you can download VC.NET express 2005 for free if you don't already have it.

The Tamarin project includes quite a few interesting things, including a utils folder containing an abc, swf and swc decompiler. You obtain pseudocode instead of AS3, but it's a start.

To compile abcdump.as, you need to compile the core builtins available in Tamarin to abc. You can do this using the Flex 2 SDK, like so:


java -jar asc.jar builtin.as
 

You get a builtin.abc file as the output. You also need the ByteArray class which is found in the shell folder:


java -jar asc.jar ByteArray.as
 

Now we're ready to compile abcdump:


java -jar asc.jar import builtin.abc -import ByteArray.abc abcdump.as
 

Now that we have the abcdump.abc file, we can run it using avmplus and decompile any .abc file we stumble upon, for example playerglobal.abc:


avmplus abcdump.abc playerglobal.abc
 

It's also possible to create an exe file using the asc compiler with the -exe flag. Thus:


java -jar asc.jar -exe avmplus.exe -import builtin.abc -import ByteArray.abc abcdump.as
 

And thus we get a reusable, command line decompiler by the name of abcdump.exe. How cool is that? Tamarin also includes several interesting files for File IO and other magical stuff.

A first ActionScript decompiler

I's possible to use the Tamarin File IO to dump the decompiled output of the decompiler to a file. This is the seed for the abcDump decompiler. To use:


D:\ASC>abcdump
AbcDump
usage:
abcdump <filename>
 

You can download it here (click the AbcDump.zip link appearing at the end of the post).

My comments

I tried it with the amfphp service browser, and I get a 7 MB servicebrowser.il file which is a bit cryptic but fairly readable nonetheless. For example the original RawAmfService class looks like this:


public class RawAmfService extends EventDispatcher
{
        public var gatewayUrl:String = "";
        var loader:URLLoader;
       
        public function RawAmfService()
        {
                loader = new URLLoader();
                loader.addEventListener('complete', readData);
        }
        ...
}
 

And the decompiled class looks like:


class RawAmfService extends flash.events::EventDispatcher
{
        var gatewayUrl:String = ""        /* slot_id 0 */
        var loader:flash.net::URLLoader        /* slot_id 0 */

        function RawAmfService():*        /* disp_id -1*/
        {
                // local_count=1 max_scope=1 max_stack=3 code_len=40
                0     getlocal0            
                1     pushscope            
                2     findproperty          gatewayUrl
                5     pushstring            ""
                7     initproperty          gatewayUrl
                10    getlocal0            
                11    constructsuper        (0)
                13    findproperty          loader
                16    findpropstrict        flash.net::URLLoader
                19    constructprop         flash.net::URLLoader (0)
                23    initproperty          loader
                26    getlex                loader
                29    pushstring            "complete"
                32    getlex                readData
                35    callpropvoid          addEventListener (2)
                39    returnvoid           
        }
        ...
}
 

I find it interesting that gatewayUrl seems to be set to its default value in the constructor. The next step would be to translate the .il file into something more readable. The fellow at iteratif mentioned that he was working on that, although I am not sure of the current status. You can contact him at contact AT iteratif DOT net if you're interested in working something out with him.

Filed under: News
Name that site

Posted on Friday 5 January 2007

Question for you guys: I'm trying to remember the address of a Flash site which has a really cool loading bar. The loading bar's top and bottom lines are bezier curves that morph into other curves in a random fashion. Was it a .nl of some kind? You shall be rewarded with my eternal recognition and by a blog post outlining how to create such an effect.

Filed under: News
Clearing the FUD on amfphp’s speed versus JSON and XML

Posted on Saturday 16 December 2006

I just read Mike Potter's blog post on his speed comparisons between amfphp, JSON and REST-style vanilla XML, and I'd like to clear some FUD, as I believe it is unfair both to amfphp and JSON (was on vacation at the time it was published). I am sure that Mike had no bad intentions when he wrote this, as he has invited me to write an article on amfphp at DevNet and steadily covered progress in amfphp over the past months, but I think his article is a bit misguided.

The key thing here is that there are several elements to consider when comparing speed between RPC models. The post, while being well-intentioned, doesn't differentiate between these different steps, and so gives a skewed view of what influences responsiveness in an app.

In most any RPC model, there are the following steps:

  • Serialization of the request on the client-side
  • Uploading of the message to the server
  • Deserialization of the request on the server-side
  • Dispatching on the server-side
  • Serialization of the response on the server-side
  • Downloading of the message to the client
  • Deserialization of the message on the client-side

So, first things first. The client may need to serialize a request to the server-side. In the AMF case, the serialization is done in C in the Flash player, so it's extremely fast. In the JSON and XML cases, it's a little more complicated. If the sent data is "simple", then trivial serialization needs to be done through the query string. If it's not "simple", then in the JSON case it would need to be encoded using an ActionScript class, and in the XML case it would need to be constructed manually.

Then comes the uploading. The question is: how efficient is data encoding in AMF vs. JSON vs. REST-style XML? Well, if we examine the data being sent through the MochiTest.getTable example, which is behind this page, we find that the result is about 800 bytes when coming back from AMF and about 400 bytes when coming from JSON. But there's a catch here. When AMF is used, it sends back a few headers and a surrounding body to deal with such things as batched calls, while JSON doesn't. This surrounding data accounts for about 300 to 400 bytes per request. So if instead of sending back 5 results, we sent back 500, we would get a dead heat between JSON and AMF with about 40KBs each, give or take 2-3 KBs. In some cases AMF is more efficient: for long strings, for example, say 100K long, AMF would beat JSON by about 400 bytes, assuming that one character in 256 is a double-quote. AMF also has a reference counter for strings and objects, so if you repeat a lot of the same data, it will win. If it sounds like I'm splitting hairs, it's because I am. Both formats are very, very efficient and granted that you use an appropriate data structure for both, they will almost always stay within 10% of the size of each other.

What about XML? Well, since I'm using a MochiKit example, I looked at the equivalent XML furnished in the toolkit and it's about 800 bytes (after removing whitespace), so it's twice as big as the other two. Of course there are many ways in which the schema could be optimized, but it begs the question: should I really be thinking about optimizing xml schemas instead of features? Admit however that we have some smart cookie of a developer who does think about such things, then we can reasonably expect XML to be about 50% more verbose than its equivalent JSON or AMF representation.

Then comes the deserialization of the request on the server-side. If we are passing arguments through the query string in JSON or XML, then there is practically no processing involved. If not, then the data will need to be deserialized manually by the developer in the XML case or through a function using JSON. In the AMF case, the gateway will deal with the details of deserialization, which will certainly be slower than dealing with query-string arguments, but it should be about the same speed as deserializing JSON using a PHP class such as PEAR JSON (more on this later).

Now, as for dispatching, the Rest-style XML usually has a one-to-one correspondance between remote methods and php pages, so it's a very simple system that doesn't have any overhead. The JSON case is similar as well, if you write the code yourself. Amfphp has a dispatching mechanism which can deal with batched calls, debugging info, security and instantiating your classes which adds some overhead. How much overhead? Somewhere in the range of 1-5 milliseconds per call. This overhead is the same in AMF mode and with the new JSON mode.

Now, for the serializing. If you use Rest-style XML, you have the speed advantage, as you know the data being sent, and therefore you don't have to if..else clauses to determine how data is being written. In the AMF case, then the serializing is done through PHP, and it determines types for you, so it's slower. The PEAR JSON case is very similar to the AMF case. However, if you use a native JSON extension, such as is built-in in PHP 5.2, serializing is going to be very, very fast. Faster than both the XML and the AMF case. The JSON extension page states that you can expect it to be 50 to 100 times faster than the equivalent PEAR JSON case. That's really, really fast kids.

The downloading is the same issue as the uploading, and here AMF and JSON are significantly more efficient.

The deserializing on the client-side is native in the AMF case, so it's very fast. In the XML case, if you're using AS3, then it should be fast, although trying to use XPath on 5000 records like in Mike Potter's example might slow the player to a crawl if you're using AS2. JSON here lags behind because it's not native.

Interpreting Mike's results

I hope that I've been sufficiently "fair and balanced" here. I don't want readers to feel that I've used loaded terms or discredited the other sides for partisan reasons. With that in mind, let's interpret Mike's results.

First off: JSON. Why is JSON significantly slower than the other two? Two things: first of all, serialization on the php side. Zend JSON was used, and according to this test, it's about 20-50 times slower on encoding than the PHP C extension. Using json_encode will yield much closer results. Second of all, decoding on the client-side is done through ActionScript, and for that much sent data, that is going to be a major bottleneck, IF there is lots of data being sent, as in Mike's test case. For reasonable amounts of data, such as that you would receive from Flickr for example, decoding is not going to be such a bottleneck, especially if using AS3.

Second of all: REST-style XML. Of course it's faster than the other two solutions. It's native in the player, so it doesn't suffer from the decoding bottleneck. The tests were done through localhost, so the significant difference in message size is not taken into account like it would be in the real world. In fact, one of the readers commented:

"in my tests, the AMFPHP was faster of what the XML the test remotely (my emphasis) it made the difference =)

Best Regards Leonardo França [This matches what Adobe consulting told me as well... I suggest that people do their own tests on their own applications. - Mike]"

Finally, for amfphp, the main bottleneck is definitely the encoding step on the php side. Decoding and dispatching take a very low amount of time, ncoding/decoding on the client-side take almost no-time, and the test is through localhost, so any difference in message size will not have been noticed. So all what we're testing when comparing the speed of Rest-style XML vs. amfphp is the speed of the encoder. Well amfphp seems to be about 25%-40% slower in this case, and I think considering all the internal processing that goes on to encode the arrays and type everything automatically, amfphp does a really good job in this case.

All the XML code does is loop through the array and output a string. In the amfphp case, it goes through the serializer's writeData method. The writeData function then asks: is it a string? is it a boolean? is it an array? Yes. Is it an associative array? Yes. Then encode an object. Then for each element in the associative array, it asks: is it an int? Is it an object? Is a string? Yes. Then encode a string. And so on for 5000 iterations. That it would hold its own in such a stress test shows that I must have done some good ;)

In fact, it's a bit too fast to accurately represent what it really does. In fact the DataGrid component must be taking a good amount of CPU time to render all the elements, and that's probably why XML doesn't beat amfphp by a large margin in this case.

So, while I think the example is contrived, amfphp does a really good job here, as others have verified that the slower encoding is made up by the native support in the player and by the significant difference in message size. So even though this example puts amfphp in the worst possible light and exploits its bottlenecks, the fact that when the test is run live through an internet connection, it still beats xml, hands-down, is quite impressive. But...

It's not a realistic test case

Would you really send 5000 rows back to a client for the fun of it? Well, I hope you're smarter than that. Real-world use of amfphp, xml and json is very different. It's possible to send that much data back to a client, for various reasons, but the data will look very different. Let's see a real-world example.

The app: Zillow. This app sends a load of data back and forth through the wire to update the house lots and such. The first time I looked at it through ServiceCapture I had noticed it sent most of its results through XML. Now it looks like they are slowly migrating to JSON, which I think is a smart move. Let's look at a service invocation to a page called RetrieveParcelResults:


<parcelresults>
   <messages>
      <warning>
         <message>There are too many homes to display. Please zoom in.</message>
      </warning>
   </messages>
   <query>
      <region>[mapped area]</region>
   </query>
   <results></results>
   <map>
      <regions>
         <zindexregion>
            <name>Kitsap</name>
            <fullName>Kitsap</fullName>
            <regionType>County</regionType>
            <zindexValue>$276K</zindexValue>
            <geoPageUrl>/local/Washington/Kitsap</geoPageUrl>
            <regionBounds>
               <bottomLeft>
                  <latitude>47.403172</latitude>
                  <longitude>-123.036507</longitude>
               </bottomLeft>
               <topRight>
                  <latitude>47.938976</latitude>
                  <longitude>-122.443352</longitude>
               </topRight>
            </regionBounds>
            <location>
               <latitude>47.671074</latitude>
               <longitude>-122.73993</longitude>
            </location>
         </zindexregion>
         <zindexregion>
            <name>King</name>
            <fullName>King</fullName>
            <regionType>County</regionType>
            <zindexValue>$421K</zindexValue>
            <geoPageUrl>/local/Washington/King</geoPageUrl>
            <regionBounds>
               <bottomLeft>
                  <latitude>47.084343</latitude>
                  <longitude>-122.539398</longitude>
               </bottomLeft>
               <topRight>
                  <latitude>47.780499</latitude>
                  <longitude>-121.064598</longitude>
               </topRight>
            </regionBounds>
            <location>
               <latitude>47.432421</latitude>
               <longitude>-121.801998</longitude>
            </location>
         </zindexregion>
      </regions>
   </map>
</parcelresults>
 

I'm sure you can imagine the code required to generate that. If it was PHP (it's most likely Java as there is a JSESSIONID in the cookies, but for the argument's sake), it would likely look like this:


<?php

//Assuming the data has been received beforehand
$xml = "<parcelresults><messages>";
foreach($messages as $message)
{
    $xml .= "<" . $message['level'] . "><message>" . htmlspecialchars($message['message']) . "</message></" . $message['level'] . ">";
}

$xml .= "</message>";
$xml .= "<query><region>" . $_GET['regionType'] . "</region></query>";

//and so on and so and so forth for another 50 lines or so

$xml .= "</parcelresults>";
echo $xml;
?>
 

Of course, if this were amfphp or JSON, that whole xml serialization step would be skipped. On the Flash side, since they are using AS2, it would be as painful as on the php side, unless they are using XPath, in which case it would slow it down a bit. Also, everything returns as a string, so they will have to wrap location.latitude and location.longitude in Number(). As far as size goes, well, specifying only two locations yields about 1KB of data. If they had 100 locations (as could definitely happen with house lots), that would be 50KB right there, while the equivalent JSON or AMF would surely be under 20KB. Yes, they could shrink the size of the XML by changing schemas, but they wouldn't have to think about schemas if they had used AMF or JSON.

So, think to yourself: How much time was wasted by the developers to think about the current schema? How much time did they have to play with the code so they wouldn't forget the occasional htmlspecialchars or \"? How much time was wasted on debugging that thing? How much time was wasted while the client was waiting for the XML file being downloaded? How much time was wasted while the client processed the info using XPath or childNodes.childNodes.childNodes?

It is in these real world situations that JSON and AMF shine. And when I talk about AMF, I don't mean just amfphp, I mean SabreAMF, WebOrb, OpenAMF, Fluorine, Adobe's offerings, Red5 (soon to come), you name it. That I can take the same PHP file and make it run as a service in SabreAMF, WebOrb or amfphp with practically no modifications speaks volumes. Similarly, I can take a Flash file, change the gateway location and plug my RIA that was developed with amfphp into Fluorine.

In those real world situations, JSON and AMF will not only be faster to develop, to deploy, and to debug, they will be faster to run thanks to the efficient message encoding and built-in language support (meaning, JSON in JavaScript and AMF in ActionScript).

Conclusion

Don't get me wrong, Rest-style XML has its uses. If you want to read an RSS feed for example, I wouldn't suggest passing it through amfphp (as some have suggested in the past). If you're using a ready-made web-service that is only available through SOAP, then by all means do it.

If a provider, like Flickr or Yahoo!, gives you the choice between JSON and XML in an AJAX app however, I would definitely suggest using the more efficient JSON. If you have the choice between JSON and XML for a Flash app, I would say it's a toss-up (decoding being non-native in the JSON case, XML being more bloated in the other case).

Now if you're developing the back-end services yourself, then please, by all means, use AMF if you're using Flash, and JSON if you're using AJAX. You don't have to choose between the two, now that amfphp and WebOrb are moving towards unified platforms for both. In the end, using what's native makes the most sense.

Filed under: Remoting and Actionscript and PHP and Flash
Amfphp 1.9 beta - Get it now

Posted on Saturday 16 December 2006

* Update: a second beta is now available here *

Well I've been working on the new version of amfphp for about a week now, and it's ready for a test-drive. I've had the feedback I needed from the alpha, and I am fairly convinced this new version works like a charm. You can download it here. This time it should work with PHP4.

What's new

  • AMF3 support, including RemoteObject. You can finally use it in Flex 2.
  • JSON support. In addition to gateway.php, there is now json.php which allows you to use your services in JSON as well Flash. Two examples here: MochiKit and Spry. XML-RPC also supported. Details below.
  • A new Service Browser. Try it live here. Notice that the samples.MochiTest service is the same one used by the JSON sample, so you can verify for yourself that indeed it works both in AMF and in JSON mode. Fuggawesome.
  • The end of $this->methodTable. From now on, $this->methodTable is ignored. All methods are remotely accessible by default. Details below.

Getting it running in Flex 2

This has nothing to do with amfphp per-say, but to get RemoteObject running, you need to configure the Flex compiler by doing the following:

  • In you source folder, create the services-config.xml file. Paste this in (You can change the uri of the endpoint if you wish):

<?xml version="1.0" encoding="UTF-8"?>
<services-config>
    <services>
        <service id="amfphp-flashremoting-service"
                 class="flex.messaging.services.RemotingService"
                 messageTypes="flex.messaging.messages.RemotingMessage">

            <destination id="amfphp">
                <channels>
                    <channel ref="my-amfphp"/>
                </channels>
                <properties>
                    <source>*</source>
                </properties>
            </destination>
        </service>
    </services>

    <channels>
        <channel-definition id="my-amfphp" class="mx.messaging.channels.AMFChannel">
            <endpoint uri="http://localhost/amfphp/gateway.php" class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>
</services-config>
 

  • Right-click your project in Flex Builder 2 in the Navigator, go to Flex Compiler, and add -services "services-config.xml" to Additional compiler arguments. Press OK.
  • You can override the gateway location in RemoteObject if you want by setting the endpoint property in the MXML. This is good as you have to clean your project in order for changes to services-config.xml to be caught by the compiler, which means rebuild from scratch. Also, that XML file is painful to look at compared to good old mxml.

About JSON support

Before people start crying about feature bloat, let me put things in perspective. There are two files in the json directory, totaling 5k. That's it. Amfphp has had a JSON parser in it since amfphp 1.2 (the PEAR version, for the service browser), so it didn't need a lot to get it to support JSON.

How it works: To make a request, call /json.php/com.mypackage.MyClass.myMethod/arg1/arg2 (and so on for other arguments). arg1 or arg2 can be strings with or without surrounding quotes, numbers, arrays or objects in JSON format. The myMethod method will be called in class MyClass in the services/com/mypackage folder, with arguments arg1 and arg2 (decoded). Then you can send back whatever you want and it will serialize automatically. If you use NetDebug::trace it will add that in a comment before the actual data. It will serialize recordsets like amfphp does by creating an object which has two keys: "columns" (an array) and "rows" (an array of arrays). You can then easily manipulate this data in JavaScript. If you want to use it with Spry, you can see my example jsondataset.js file which does all the job for you (if anybody at Adobe is listening, you can add it or something along the lines of it in the next version of Spry). If you add POST data to your request it will be deserialized as JSON and you will receive it as the last argument to your method.

Now, why would you use JSON in amfphp instead of, say, library X? Well:

  • You can use the same service in JavaScript AND Flash.
  • You can use the service browser to test your classes.
  • Most PHP Ajax libraries mix and match code and presentation in a fashion which makes me sick to the stomach. Amfphp provides a clean way to organize your code and dispatch calls.
  • It will use PHP's json_* functions if it finds them (built-in in PHP 5.2, available as an extension in older versions), or will revert to PEAR JSON if it doesn't, so you have an easy upgrade path if you need more speed.
  • It will serialize recordsets directly.
  • It doesn't have any JavaScript dependencies, so you can use with whatever toolkit you like (prototype, MochiKit, Spry, you name it).

(I would also say personally that it's entirely fuggawesome, but I think I've already made a pretty strong argument for that).

About XML-RPC support

XML-RPC is similar to SOAP except that it doesn't rely on those godforsaken .wsdl files. It's a lot more verbose that JSON-RPC or AMF-RPC but it's readable, and if you enable gzip compression it's not that bad as far as size goes. It could be useful if you want to share your awesome new service with XML-heads. It requires the xmlrpc extension to be installed. Just call xmlrpc.php through POST and it should work like you expect it to (that is, it uses the same kind of mapping as the "normal" amfphp does, it'll serialize recordsets, etc.)

About the new Service Browser

The new Service Browser rocks. Try it out here if you like. A thing I want to point out is that if you have a fatal error in your service file, it will catch it and not NetConnection.Call.BadVersion on you. That's because it's writing and reading its own amf packets and will do some sanity checking (try calling HelloWorld.triggerAFatalError). It will also show NetDebug::trace output in the "trace" tab, despite this not being supported by RemoteObject for some reason (again, because it's reading and writing it's own amf packets). That being said, the non-test calls are routed through the regular RemoteObject so if there is any discrepancy between my code and the one the player outputs it should be caught early.

If your service uses session you WILL need to use the service browser in a web browser that accepts cookies as I have yet to figure out how to make it honor AppendToGatewayUrl headers.

I need you help with the service browser. I want it to be better, but I don't have that much time, so here's my laundry list, the source is right here, please comment if you're interested in taking on these items.

  • Clean up the current spaghetti-code mess
  • Add Code Generation
  • Make util/MethodTable smarter so it will catch more comments related to a function
  • Show all JavaDoc tags in the service description, not just the param and returns tags.
  • Format HTML properly when encountered
  • Make the Tree view work for any and all objects
  • Make the DataGrid view work when a RecordSet is nested inside something else
  • Make it look better

About $this->methodTable

It's gone for good. The single most annoying thing about amfphp has now been removed. All methods in classes of the service folder are now remotely callable by default. You can make a method non-remote by starting it with an underscore (same as with CakePHP), or by making it private or protected (PHP5 only). You can stop a method from being called (for example, for lack of proper credentials) by creating a beforeFilter($methodName) method and returning false to stop the call (same as with CakePHP, again).

_authenticate support has been temporarily removed (can be done with beforeFilter now), and pageable recordsets have been temporarily disabled as well. New methodologies will be introduced for these features in amfphp 2.0 final.

About recordsets

Currently, only mysql recordsets work. Since amfphp serializes about a dozen different recordset types normally, and I have made a bunch of changes, I will wait until everything is stable before re-enabling the other recordset types. If you need support for those types now, you can rewrite core/shared/adapters/dbnameAdapter.php, using mysqlAdapter.php as a guide.

Acknowledgments

This release would not have been possible without all the hard work of several people who I have borrowed code and ideas from. Big thanks to Zoltan of Fluorine (AMF3 code), Evert of SabreAMF (RemoteObject code), Karl of Charles debugging proxy (debugging needs), Kevin of ServiceCapture (first reverse-engineered AMF3), Aral Balkan for his suggestion of a Flex-based service browser, Renaun Erickson for his PHP4 array_search patch and VO handling code, the people at CakePHP for some of the JSON code, the people at PEAR::JSON, and Christophe Herreman for his original MethodTable class which is now the core of the Service Browser component.

Filed under: News
Call to arms: amfphp with Flex Data Services functionality

Posted on Tuesday 12 December 2006

I recently got amf3 features into amfphp which means it is finally compatible with Flex 2's RemoteObject tag. Sweet. While I am waiting for feedback on these new features and iron out the issues, I'd like to get started on getting Flex Data Services functionality in amfphp. Flex Data Services, from what I gather of it, can do crazy things like managing remote SharedObjects, keeping clients in sync on recordsets, paging results, and implement remote data-binding-like functionality. Really nice stuff. Now I'd like to bring at least some of that into amfphp. We may not be able to replicate everything in the framework, but if we could only get SharedObject functionality in for example, I am sure many would be ecstatic.

That's where you come in. I need someone to document the different types of messages that can be sent and received from Flex Data Services. All you need is Flex Builder, Flex Data Services, and the latest copy of Charles to help me out. It should be as simple as making some sample Flex apps, firing up Charles and doing a couple of operations to figure out what the messages mean. I would need the results in a text format, something along the lines of:

Flash player sends flex.messaging.io.CommandMessage with empty body, operation 5. FDS sends back flex.messaging.io.AcknowledgeMessage with empty body, correlationId set to CommandMessage.messageId. Interpretation: Ping message

Flash player sends flex.messaging.io.CommandMessage with empty body, operation 0, when mx:Subscriber.subscribe call is made FDS sends back ??? Interpretation: Subscribe message

I would like to do it myself but unfortunately I don't know (much) Java and I can't get Flex Data Services installed on my laptop because my hard drive is full, and I also am lacking in time.

Getting Flex Data Services into amfphp would be a great thing for developers. IMHO, Flex Data Services is rather difficult to approach, yet it is very powerful. If people could get FDS functionality while not requiring a dedicated server to host FDS, it would mean more developers could get into the game. It would also create a simple migration path from amfphp to FDS, which would be beneficial for me, you, the users, the developers, Adobe, Ted Patrick, your mom, etc. etc. The person(s) that will help me in this will get my (and the community's) eternal thankfulness, and a warm-fuzzy-feeling inside. If you're interested, please comment, or send me an email at pm AT 5etdemi DOT com.

Filed under: Remoting and PHP and Flash