The AMF file format is a binary file format representing a serialized ActionScript object. This file type is used in many places within the Flash Player and AIR for data storage and data exchange. In Flash Player 9 and AIR, the flash.utils.ByteArray class is the primary way AMF is handled. Let's look at some examples:
//create some AMF within a ByteArray
import flash.utils.ByteArray;
//create a bytearray
var bytes:ByteArray = new ByteArray();
//write an object into the bytearray
bytes.writeObject(
{ myString:"Hello World" , myNumber:21 , myBool:true }
);
When you write an object into a ByteArray it serializes the object into aa array of bytes using the AMF file format. You can then transfer this file over a network or save it to a file system to be deserialized later. Let's deserialize AMF:
//create an object and deserialize an object from a bytearray
var myObject:Object = bytes.readObject();
//trace a property
trace( myObject.myString ) // Hello World
In this case the myObject variable looks exactly like the object that was originally put into the ByteArray. Once the AMF data is transformed into a real object again, we can use it in ActionScript identically as before.
In Flash Player AMF is used in SharedObject, RemoteObject, LocalConnection, ByteArray, RTMP (all variants) and all RPC remoting operations. The benefits of AMF are actually really misunderstood, so lets take a quick look:
1. File Size - AMF objects are very small and are compressed using zlib.
2. Fast Serialization/Deserialization - AMF is transformed using native C code in the player so it is blazing fast. The AMF format was designed to serialize and deserialize quickly under low memory and slower CPU conditions. As the AMF data is parsed directly to objects, there is no lag for interpretation or parsing of AMF and creation of objects is done on a single pass.
3. Native Types and Custom classes supported - You can serialize any object in Flash Player with the only exception being displayObjects. You can also map serialized objects back to custom class instances provided the custom class is in the Flash Player when things are deserialized.
I hear many folks talk about remoting with Flash Player but there is a lower level to remoting in using AMF directly. What is cool here is that you are not limited to traditional RPC using HTTP/HTTPS as Flash Player 9 supports binary sockets in the flash.net.Socket class and stream loading of AMF using flash.net.URLStream class. Better still, you can use AMF to store data on the server side without the server needing to know anything about the objects themselves. It is an ideal way to exchange data and persist objects to disk or to the network.
I would encourage you to take a deeper look at AMF. There are some low level benefits to using it that are hard to beat. With all distributed computing systems, serialized object formats are essential and AMF is the native format for Flash Player.
There is some big AMF news coming in December.... :)
Cheers,
Ted :)
DIGG IT! 
So I see a chance that the specs are finally opened !? Keeping thumbs crossed.
Ah and while hoping for that how about open spec for RTMP? ;-)
Excellent write up Ted. I heart AMF. Is the zlib compression new to Flash Player 9/AS3? I seem to remember from back in my remoting days that AMF wasn't compressed?
When you coming down to Disney to meet with us :)
AMF has definitely had me interested for a while, after seeing the comparison charts with AMF versus E4X performance. However, I haven't been able to get my head around how you replicate the elegant structure of XML objects in AMF. Do you basically just send a list of nested ByteArrays?
In saying:
Flash Player 9 supports binary sockets in the flash.net.Socket class and stream loading of AMF using flash.net.URLStream class.
<<
We still need server-side help like LCDS, don't we?
?????????? ? ???????? AMF
Scott, AMF3 is the spec added in FP9 and string elements within AMF are now zlib compressed.
zlib has been in Flash Player since FP6 when the AS blocks of SWF were compressed using zlib.
Additionally the ByteArray supports this directly in the compress and uncompress methods. Basically you pass in any ASCII text and the compressed bytes are written to the bytearray.
Scott, I will be coming down to Disney in December, I need to catch up with the teams there.
Regards,
Ted :)
Brett,
There are two options:
AMF just represents native AS objects so you can make it represent anything you want.
E4X is super handy for querying the data and returning collections after parsing to xml. That said XML is a native object and can be included in AMF3. The data is stored as a string zlib compressed and when deserialized becomes an XML object again.
bytes.writeBytes( new XML('<hello/>') );
This gives you zlib compression and benefits of e4x in one go. zlib is very effective on xml and can compress documents as much as 20X, I have seen 300Kb XML files become 7K given tag redundency in the ASCII text.
Best of both.
Ted :)
Choices here are 100% open and non-propriatary and you can use anything server side!
flash.net.Socket requires a TCP/IP based socket server although you can talk using HTTP 1.1 (persistant connections). I would recommend looking at serveral types of socket servers in java, .net, python etc.
flash.net.URLStream uses HTTP so any web server will work. The key is that you recieve a bytearray stream of data from the server. If the server does not close the http connection you can keep pushing data down the wire. This is how http based messaging is done in LCDS. One request sends data, while a URLStream listens for data pushed from the server.
The server side doesn't need to write AMF as you can store these as files on any http based server. Server-Side AMF simply allows you to manipulate and generate objects server side but you can let the client do the packaging of the AMF.
Using all this is 100% free with no strings attached. It is there to take advantage of, I am astonished more people aren't.
Cheers,
Ted :)
big AMF news coming in december ?
could it be that you guys gonna finally document the format and maybe open it ?
com'on don't let us holding our breath :)
Please, please, please, open the format. It will help us write a AMF implementation for WebObjects.
Sweet trick on the XML inside AMF!!!
It hadn't occured to me to to do that and I've been moving towards parsing XML (and all the headaches) due to the ubiquity of text processors able to write the verbose XML
Also, I've been writing on the subject of serialization and AMF,
http://troyworks.com/blog/?p=59
I've been a fan of AMF since it was introduced, working with large data sets. I'm in particularly thrilled with the ability to serialize classes, and even evolve them from versions
http://troyworks.com/blog/?p=29
URLStream is nice but is not able to produce any event of loaded data until an average chunk of 8 kbytes is available client side. This buffer is enormous when talking of bytes… Could someone at Adobe removes this huge buffer that limits the use(-full) of URLStream.
Nice article BTW Ted. Thanks
Ted, thanks for the comments. I think it'll just take me playing around with AMF to get a real feel for it. Definitely sounds promising, though!
Well it will be nice if the documentation gets updated.. I don't have time to traverse blogs, and nit-pick outdated docs to try and get this to work with ASP.Net. Would love to see some current postings on these "exciting" details..
How much longer do we need to wait.....
I'd love to see a native C library similar to the code Flash Player uses to transform AMF released on labs if the "open format" predictions come true.
URLStream is dependent on the networking in the browser. I talked to several player engineers yesterday and they confirmed that the ProgressEvent is dispatched when the browser networking provides data to the player.
Is there a particular browser where you are seeing the issue?
Ted :)
[quote]Is there a particular browser where you are seeing the issue?[/quote]
Yes Ted, all :P ! (osx and win)
I wonder if it couldn't be an issue coming from the server ?! Even wireshark doesn't capture packets less than 7,8 Kbytes in my case.
I wonder if I could take the time to build a mini server to test further ?
But you should be right in saying that it could be a limit of the HTTP client also. Using it to capture the data directly produced the exact same behavior than in the flash player.
This seems like a server issue, what http server are you using?
Running Apache 2, I was seeing initial data size of 512 bytes before the data event fired.
I was exploring this yesterday in regards to streaming images PNG/JPG/GIF and rendering the as data arrives (monday's post). It seems like you can get very fine grained with this.
Ted :)
ok thanks for looking at it.
I am using Apache 2.2.6 on osx 10.4.11 in the xampp distro (apache friends).
But I don't think it could be a server issue. Check that url :
http://projet.v-i-a.net/tmp/TextStream.html
It's a URLStream connection that loads a 100kb input stream. Each chunck of 7kb, the serverside thread is put asleep for 3 sec.
>?php
$i=1;
while ($i++ < 1000 *1024)
{
printf ( "%c", rand (0, 256) );
// Buffer client de 7,8 Kbytes
if($i % (7* 1024) == 0) sleep( 3 );
}
?<
On my mac, I have to wait the first 3 sec (+ ~ latency) to see any output in the textfield.
In IE windows virtualized, same.
Can you check on windows for me ?
So then, whose the responsible of this buffer ? :)
ok, so the browser is seeing the exact sam issue independently in every case viewing this loaded url:
http://projet.v-i-a.net/tmp/textStream.php
I get no data until 3 seconds has passed then the screen shows a bunch chars in binary.
Can you post the full source urls for the php and the flex code.
Something is wonky here.
I have done tons of work and have yet to see this error using URLStream.
Feel free to email me off comments at ted@adobe.com, I would like to understand this one and post a fix or more detail.
Ted :)
At the start of your php code add this:
ob_implicit_flush(true);
ob_end_flush();
This changes the implicit buffering in php to automatically flush the output buffering to every call to print(). With URLStream I believe this will dispatch the progressEvent much more frequently and this fix the issue.
Ted :)
Ted, definitively, you're the man !
Thumb up ! That solves the issue.
Then the issue came from a server buffer…
I did test with several servers (tomcat, apache…) and always add this trouble. That why it came to my mind it was a client buffer.
You could check the url, I've added the ob_implicit_flush(true); as requested : http://projet.v-i-a.net/tmp/TextStream.html
Every 2", you'll receive 7Kbytes of data.
Then pauses. Then again.
We could now see real flow of data analized from the Flash player as it comes, as expected.
Thanks a bunch.
Hi Ted,
My company has an all Microsoft server Framework, including, Windows Communication Foundation and C# legacy.
I need to integrate AMF packages with WCF so that I can keep on working with Flex/Flash at the client. The server framework must be WCF because of corporative constraints.
Can you help me ???
When will AMF documentation be avaiable ???
Thanks
Is it December yet?
I'm very interested in this idea of storing raw amf files on the server side using UrlStream.
Are there any examples out there of how to go about this? An example showing how to take a custom AS3 class or classes (perhaps a SharedObject, even?), send it to the server, save it as a file, load it again from the client, and then turn it back into the original AS3 classes would be incredibly useful.
I'd be happy to post some tutorials on this, but I'm not sure what the best way to go about it is at this point. Can you provide any more specifics to get me started?
Thanks,
Shaun
I wonder all these facts are true with AS2. And is there any way to use that zlib of flash player using AS2. Although our company plans to move AS3, still our main product is using Flash 7.
So what am I doing wrong?
I am rendering a 3D stage in one swf instance and trying to have it reproduced in a second swf instance. Sending the ByteArray across the Local Connection [about 1MB two times per second], the 'pipe' clogs up very quickly. I really need to sustain about 20MB/s through the interprocess connection. So, I changed to SharedObject. Writing and reading back from disk I get an order of magnitude better results???
Brilliant thing! I would like to lear more vehicletraders.co.za
make sure to set bytes.position = 0 before calling the readObject function, or you'll end up fighting with the end of file error for an hour.
Jeremy is right
The example will not run properly without "bytes.position = 0;"
being set before reading from the bytes.
Custom types are serialized as objects unless you add [RemoteClass] to the class file.
E.g.:
[RemoteClass]
public class MyClass
...
Make sure your custom class has a default constructor (no required params).