Doing partial/resumable uploads with AIR

This post by Ryan Stewart motivated me for a little example with sockets in AIR. I wanted a way to upload files to a server with the possibility to interrupt uploads at any time and pick them up later.
So to do this I thought it would be cool if it works like streaming video to the client but just the other way around. I developed a mini protocol to do this. It works like this:

1. Client (AIR app) establishes a socket connection to Server (Java based in my case)

2. If connection is succesful client send a request which looks like this: 1 byte = operation type 1, length of the body, filename to upload as UTF bytes

3. Server checks if the file with the given filename already exists if so it responds with 1byte = operation type 1, a long (64bit) value which is the size of the file on the server or 0 if it does not yet exist.
4. Client send a package from the file starting at the size of the file on the server: operation type = 2 (1byte), length of body = length of the package, bytes of the package

and so on and so on… You get the idea.

With this mechanism the upload can be interupted and picked up any time. The client and the server always know what`s happening and were the bytes belomg to.

Warning! This is a very very over symplified, incomplete example. No real error handling, no handling for multiple clients, security?…
It`s just a prove of concept. I`m not a java developer and only hacked this together very quickly. The source is really ugly and normally I would not post something like this but as I always promise to clean up everything and post later (and rarely do ;-)) i just post them here so you can get the idea and build something sophisticated out of it.

Here is a screencast that shows the app in action.

Get the sources (again really dirty sources only use for inspiration)

Tweet about this on TwitterShare on FacebookShare on LinkedInShare on Google+Pin on Pinterest

9 thoughts on “Doing partial/resumable uploads with AIR

  1. This morning I was reading Ryan’s post. And now there is an example… what a beautiful world. :)

    I’ve some questions. Your example is not using FTP protocol, does it ? And do you know if that will be possible with FTP protocol or PHP server ?

    I love your works : parleys, flvFLV. You’re a very good inspiration source. 😀
    I’m already planing on a flex/air website using progress download, like parleys.

  2. Hi Rémi,
    no this is not FTP it`s some protocol i made up myself just to ensure the bytes are transmitted correctly. There is a problem with ftp because you cannot flush the output buffer. Don`t really looked at the issue but you`ll find it covered in several places. Here is one implementation of an ftp client: done by Maciej Maliborski.
    Not sure if he could resolve the problems as I don`t speak polish 😉
    Have a nice day!

  3. I wonder, how do you read out the 64bit long. Within the Flash player there is no way to read it, or even store it temporary. The biggest you can save is 53bits integer values.

    Greetz Erik

  4. @Erik: With bitshifting you can read them all like so:
    var p1 = socket.readInt();
    var p2 = socket.readInt();
    var myLong:int = p1 || (p2 <<32);

  5. Ehm, p2 will be shifted off. Bitshifting in ActionScript works with 32 bit integers. So if you shift em 32 to the left, you shift them off the table.

    Besides that, the myLong variable in your example is typed as an int and as such can only hold 32 bits of data.

    Greetz Erik

  6. @Eric: Euh man think I slept when i wrote this. You`re absolutely right Eric. So for my example this means we`re limited to files which are not bigger than 4,294,967,295 bits if i use uint instead of int.

  7. If you type it as number you can get up to about 9,007,199,254,740,991 (if my calculation is correct), from the documentation:

    “The Number data type can use up to 53 bits to represent integer values, compared to the 32 bits available to int and uint.”

    Greetz Erik

Leave a Reply

Your email address will not be published. Required fields are marked *