Although I thought i was well on my way in decoding the AMF3 format, it seems that there's still some stuff not working correctly.
The SabreAMF deserializer is working perfectly, but there's issues with the serializer part.. While the deserializer is built loosely and accomodating for possible bugs from a different serializer, the SabreAMF serializer has to be built as strict as possible. My own produced AMF data seems to decode fine in my own deserializer, but Flex seems to have an issue with it, and throw s and index out of range error.
The guys over at Fluorine (an AMF server implementation for .NET seem to have stuff working in their alpha builds, so I'm going to see if I can learn from their sources or maybe contact them..</a>
A second thing I learned was that there's a 4th object serialization format.. I was aware of 0, 1, and 2 (which are all different formats of serializing objects) but apparently there's also '3'. I noticed this, because I was using Charles for HTTP packages and it threw an exception on me..
Overall it seems that AMF3 is a great format for communication, but also a great overkill for the remoting aspect. The fact is that Flex heavily relies on it, which makes me want to do this, but there are definitly easier ways to encode variables, servicepaths and methodscalls. While they have done a great job in reducing the number of bytes needed to send an integer over the wire, just a simple 'Hello world' call would most likely be tripled or quadrupled in size.. I understand that we are dealing with a messaging service here, and not just a remoting protocol, but do we really need all that overhead when we're dealing with plain methodcalls?
The biggest example I have for this is AMF0 had features for connecting a call to a result (using an id) and a special field for the servicename and methodcall. AMF3 also contains all this information, but its not standing on itself, it is a protocol within AMF0. These fields and information are therefore doubled.. The 'backwards compatibility' doesnt mean much for me, because its still a new protocol to learn, and if you are new in this and want to hop straight to AMF3, you would still need to learn everything about AMF0.
Once there's a final spec for AMF3, which I will try making after SabreAMF is done (and if there isnt a good one already at that point), I will need to write about 4 levels of serialization (the byte level, AMF0 level, AMF3 level and the Messaging class structure). I feel like the classes I made for decoding this are quite efficient and not too-bad structured, but still I need a whole dosen of classes and code just for decoding AMF.. Compare that to the XMLRPC spec, which essentially does the exact same thing, but can be written in 50 lines of code give or take.
A second thing is, that the FlashPlayer first does some kind of ping call, which is a whole new http call.. and requires the entire 4 layer structure to be decoded again.. All it does is checking if the server is up and it receives an acknowledgement.
Essentially that could be encoded as:
and the reply
But instead the developers of Adobe decided they need their over-designed over-complex 4-layer AMF protocol .. While my example would be 11 bytes (excluding HTTP wrappers, and all other overhead). Their method of saying the exact same thing requires around 500 bytes.. This might not seem much, but since you can express true or false in 1 byte (1 bit actually) using 250 bytes to just submit true over the wire, is a lot. I wonder why they put so much effort in packing integers in a smaller number of bytes, since basically every other aspect of the protocol grew in bloatyness..
Fair enough, its fun doing this, but it just takes a bit more time to do it..