Archive for the ‘Flex’ Category

Flex FTP Abort

Friday, February 11th, 2011

To properly close a transfer to the FTP server, you need to send an Abort command (see http://www.w3.org/Protocols/rfc959/4_FileTransfer.html (ABORT) ). Flex FTP doesn't support this so I added some functionality to be able to send an abort.

First I added the Abort command to the Commands class:

CODE:
  1. public static const ABOR:String = "ABOR";

After that I added a new invoker to the invokers package, AbortInv.

The FTPInvoker class required a new public method to support the Abort command, which can be overridden by the specific implementations. In FTPInvoker I added an abort method like this:

CODE:
  1. /**
  2. * Stops this Invoker from executing.
  3. */
  4. public function abort():void {
  5. // Some Invokers just don't need to do anything.
  6. finalize();
  7. }

There was only one invoker where I had to override the abort method to get things working correctly and that was the UploadInv class. Here I added the following code:

CODE:
  1. /**
  2. * @inheritDoc
  3. */
  4. override public function abort():void {
  5. super.abort();
  6.  
  7. if(interval) clearInterval(interval);
  8. if(sourceFile) sourceFile.close();
  9. if(passiveSocket && passiveSocket.connected) passiveSocket.close();
  10. }

After that it was a matter of updating the FTPClient class with an abort method to get the circle complete.

CODE:
  1. /**
  2. * Aborts the previous FTP command.
  3. */
  4. public function abort():void {
  5. if(currentProcess) {
  6. if(currentProcess is UploadInv) {
  7. swallowNextResponse = true;
  8. }
  9. currentProcess.abort();
  10. currentProcess = null;
  11. }
  12.  
  13. invoke( new AbortInv(this) );
  14. }

Unfortunately I also had to update handleData method in the FTPClient class a little bit, because aborting an upload would result into 2 (or more) resonses at once from the FTP server.
My handleData method now looks like this:

CODE:
  1. private function handleData (pEvt:ProgressEvent):void
  2. {
  3. processing = false;
  4. var response:String = ctrlSocket.readUTFBytes(ctrlSocket.bytesAvailable);
  5. var responseList:Array = response.split("\n");
  6. // Apparently we always get a linebreak with a response...
  7. responseList.pop();
  8.  
  9. var eventList:Array = new Array();
  10. var evt:FTPEvent;
  11. for(var i:int = 0; i <responseList.length; i++) {
  12. evt = new FTPEvent(FTPEvent.RESPONSE);
  13. evt.response = FTPResponse.parseResponse(responseList[i]);
  14. eventList.push(evt);
  15. if (FTPClient.DEBUG) trace("->" + evt.response.code+" "+evt.response.message);
  16. }
  17.  
  18. if(swallowNextResponse) {
  19. if (FTPClient.DEBUG) trace(" - ignoring this response...");
  20. swallowNextResponse = false;
  21. responseList.shift();
  22. }
  23.  
  24. if(responseList.length> 0) {
  25. for(var k:int = 0; k <responseList.length; k++) {
  26. dispatchEvent(eventList[k]);
  27. }
  28. }
  29. }

Links

Flex + Java = Frankenstein?

Tuesday, February 8th, 2011

Lately I've been working on a small upload tool in Flex/AIR.
To verify that an upload has succeeded, I created a hash (md5) of the entire file and sent that to the backend for verification. The AS3CoreLib contains a nice MD5 class, MD5Stream, but it's much too slow for creating a checksum of files.

Actually, it's so slow that when I was uploading a 5+ MB file the application would slow down so much that the upload speed dropped to a third of the speed without feeding the MD5Stream data during uploading.
Luckily, with AIR 2.0 NativeProcess has been introduced, it made it much easier to "outsource" complicated calculation to a process that can deal with that much better, i.e. Java.

The nice thing about Java is that it's cross-platform just as AIR, and these days many people will have the JRE installed.  So first of all, I wrote a small Java class that would print out an MD5 hash of a file based on the path that I passed. I jarred the class and added it to my AIR project.
The second step was to call my Java class instead of the AS3 MD5Stream class. This is surprisingly easy. The NativeProcess documentation comes with a pretty clear example and Piotr Walczyszyn has created a small framework, Flerry, to let Flex talk to Java and vice versa.

Looking at how Flerry is built will give you some more insight on how to deal with NativeProcess.
For my application, I only use the BaseStartupInfoProvider class from Flerry to find where Java is installed on the user's machine. After that I set up all event listeners as per the NativeProcess documentation and call NativeProcess.start() with a NativeProcessStartupInfo as passed in parameter.
Now my uploads are fast again and I can generate a checksum in a fraction of the time I could before.

There are unfortunately some downsides to this approach. You have to deploy your AIR application as native installer to be able to use the NativeProcess class. So instead of having one AIR file, you'll end up with four native installers (.exe, .dmg, .deb, .rpm). On the plus side, you can create the native installers from an AIR file without needing to resign the application.
Another downside is that now I'm relying on two runtimes being installed on the end user's machine, AIR and Java.
My final thought is that now that I am outsourcing some calculations to Java, why not built the whole thing in Java? Then again, building a decent UI can take ages using Java. To me, my application feels like I'm creating a bit of a Frankenstein.

All in all I'm glad I now have a fast way to generate a checksum and my uploads aren't slowed down by it any more.

Links:

Flex FTP EPSV support

Monday, February 7th, 2011

Still working with Flex FTP and this time I was missing EPSV support. EPSV is roughly the same as PASV, exect that you only get a port number to connect to back and not an IP address. You can read up on RFC 2428 "FTP Extensions for IPv6 and NATs" if you want more details.

The first thing I did to add support for EPSV in Flex FTP is adding a response to the Responses class.

CODE:
  1. public static const ENTERING_EPSV:int = 229; //Entering Extended Passive Mode.

Second was the commands class, where I added the following line:

CODE:
  1. public static const EPSV:String = "EPSV";

Then I added an extra argument to the FTPClient class' constructor that will indicate whether or not to use ESPV.

CODE:
  1. public function FTPClient (host:String="", port:int=21, useEpsv:Boolean = false)

I store the value internally and use a getter method to determine if an Invoker class (i.e ListInv) needs to use EPSV.

Based on the client epsv setting any invoker can be updated to send the EPSV command instead of the PASV command when needed, i.e. my implementation of ListInv's startSequence method:

CODE:
  1. override protected function startSequence ():void {
  2. if(client.useEpsv) {
  3. sendCommand(new FTPCommand(Commands.EPSV));
  4. } else {
  5. sendCommand(new FTPCommand(Commands.PASV));
  6. }
  7. }

I also update the responseHandler method in ListInv to include the following case:

CODE:
  1. case Responses.ENTERING_EPSV:
  2. passiveSocket =    PassiveSocketInfo.createPassiveSocket(evt.response.message,
  3. handlePassiveConnect,
  4. handleListing, ioErrorHandler,
  5. null, true, client.hostname);
  6. break;

On top of that I made some tweaks to the PassiveSocketInfo class.
The parseFromResponse method now looks like this:

CODE:
  1. public static function parseFromResponse (pasvResponse:String, usingEpsv:Boolean = false, hostName:String = ""):PassiveSocketInfo {
  2. var host:String;
  3. var port:int;
  4.  
  5. if (usingEpsv) {
  6. host = hostName;
  7. port = pasvResponse.match(/\d+/)[0];
  8. } else {
  9. var match:Array = pasvResponse.match(/(\d{1,3},){5}\d{1,3}/);
  10. if (match == null)
  11. throw new Error("Error parsing passive port! (Response: "+pasvResponse+")");
  12. var data:Array = match[0].split(",");
  13. host = data.slice(0,4).join(".");
  14. port = parseInt(data[4])*256+parseInt(data[5]);
  15. }
  16. return new PassiveSocketInfo(host, port);
  17. }

The createPassiveSocket method now takes two extra optional arguments (usingEpsv:Boolean and host:String) and just passes those on to the parseFromResponse method.

Hope this helps anybody looking for EPSV support for Flex FTP.

PS: It's been a while since I added EPSV support, so let me know about any gaps.

Flex FTP Make Directory

Wednesday, August 18th, 2010

I'm messing around with Flex FTP at the moment and found that there is no way yet to create a directory on the FTP server. I had a quick look through the code on how the other FTP actions were implemented. Being surprised with the nice setup of the code I had quite easily added the "make directory" action and got it working properly. You can download my MakeDirInv class here: http://ansuz.nl/toys/randomcode/MakeDirInv.as
All you need to do after that is patch the FTPClient class by adding the following method.

Actionscript:
  1. /**
  2. * Creates a directory on the remote host.
  3. *
  4. * @param newDirName The name of the new directory to create.
  5. * @param parentDir (Optional) The directory to create the new directory in.
  6. */
  7. public function makeDir(newDirName:String, parentDir:String = "/"):void {
  8. trace("FTPClient.makeDir(newDirName, parentDir)");
  9. invoke(new MakeDirInv(this, newDirName, parentDir));
  10. }

Once you've done that, you're ready to create directories on the FTP server you're connected to, see the example below.

Actionscript:
  1. ftpClient.addEventListener(FTPEvent.CREATE_DIR, dirCreatedHandler);
  2. ftpClient.makeDir("myNewDir", "/someSubDir/");

PS: This isn't fully tested yet, so do let me know if you find some bugs.

Links

De MonsterDebugger

Thursday, March 11th, 2010

I'm always looking for a nice debugger to use on the fly, the "De MonsterDebugger" looks really nice.

De MonsterDebugger is an open source debugger for Adobe Flash, Flex and AIR. De MonsterDebugger is made in Flex and AIR by design studio De Monsters.

One of the nicest features in my opinion is the live editing of properties, very handy when fiddling to position elements correctly.

Links:

Phidgets / Arduino

Wednesday, January 20th, 2010

I'd love to have some time to mess around with a Phidgets or Arduino board, it looks like a lot of fun! Using Flash to control something analog/physical! :D

Flex IRC Client

Thursday, January 14th, 2010

Just came across this when browsing around a bit. This Flex IRC client is a port of the Java-based PircBot.

Flex IRC Client aims to be a Flex / Flash based IRC Client. Currently most browser-based chat solutions are either proprietary or applets. Flex IRC Client wants to bring the power of IRC to the majority of the Internet-users without requiring a download or an install.

I know this client is still under development, but it could really do with a window showing some progress when connecting to a server. Also, a proxy of sorts would be nice since I get a lot of Security Errors when trying to connect to a server: "SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048: Security sandbox violation: http://ansuz.nl/toys/irc/FlexIRCClient.swf cannot load data from irc.efnet.nl:6667."", probably due to no cross-domain policies being set on the IRC servers. Connecting works when running this locally ;)

Links

AS Frameworks

Tuesday, December 15th, 2009

Recently I've been looking into different frameworks, just to get some experience with other interesting frameworks out there. I've compiled a list of some of the frameworks I've found. I'm sure I've missed a couple of other good ones, if you know of one, please let me know. :)

Gaia
A framework package as a Flash component. Handy for designers, but it kinda made me shrug... Though reading through the docs a couple of interesting features showed through, like the generation of the navigation through the context menu.
Link: http://www.gaiaflashframework.com/index.php

Cairngorm
Used this framework / micro architecture a lot already. Nice Event-Command pairs as well as delegates for calling all (web)services.
Link: http://opensource.adobe.com/wiki/display/cairngorm/Cairngorm

PureMVC
I've been working with a PureMVC project lately and looked at it before, quite similar in some ways to Cairngorm, just different names. ;)
A nice resource for pureMVC: http://puremvc.tv/
Link: http://puremvc.org/

Swiz

Swiz is a framework for Adobe Flex that aims to bring complete simplicity to RIA development. Swiz provides Inversion of Control, event handing, and simple life cycle for asynchronous remote methods.

Link: http://code.google.com/p/swizframework/

Dawn

Dawn is a lightweight framework for ActionScript inspired by Google Guice. In addition to Dependency Injection, it provides type safe notifications and helps you to build apps which are loosely coupled, easily unit tested, and less error-prone.

Link: http://wiki.github.com/sammyt/dawn

Mate

Mate is a tag-based, event-driven Flex framework.

Mate framework has been created to make it easy to handle the events your Flex application creates. Mate allows you to define who is handling those events, whether data needs to be retrieved from the server, or other events need to be triggered.

In addition, Mate provides a mechanism for dependency injection to make it easy for the different parts of your application to get the data and objects they need.

Link: http://mate.asfusion.com/

I think I'm going to give Dawn a try soon enough, of all the above it looks the most interesting to me.

AS3 Version Injection + Flex PMD + TDSI = Rock ‘n Roll! \m/

Wednesday, October 21st, 2009

AS3 Version Injection

Ever been annoyed by Project Managers telling you that a bug you fixed is still in the latest release you did and after some investigation find out that they forgot to clear their cache? Well, fear not! An AS3 Version Injection script is here! :P
I've created a simple AS3 class called Version that will add a time stamp to the context menu. All you need to do is instantiate the Version class once and pass it a reference to you Document Class. On top of the AS I've written a little Ant script that will take a template of the Version class, insert the current date and time and write out the Version class. This way you can just make it part of your Ant build and don't need to worry about manually updating the version number. Also, now you'll have a way of quickly identifying what version somebody is looking at. :)

Flex PMD

This is great for auditing your own code as well as other people's code. I've written a small Ant task that can be ran as part of a build that will run your project through Flex PMD and create a PMD file for you. The PMD file will have a time stamp suffix so you don't overwrite your old file and you can compare issues. To use this Ant script make sure you've downloaded PMD for Ant.

TDSI

Another piece of very useful technology. Up to 20% performance increase just by passing your SWF through it. I downloaded the Apparat source (where TDSI is part of) from Google Code and compiled it. Built another little Ant script to use TDSI with Ant. Just specify the input and the output file and you're done!

Bringing it all together

All the above Ant scripts are saved in a separate file. This way I can import whatever piece I want in my build script, example:

XML:
  1. <import file="as3_version.xml" />

TIP: Place the import after you have defined your properties in the build script, this way the imported scripts can use the properties set in the build script.

Links

Flex PMD

Tuesday, October 13th, 2009

Nice! A Flex (automated) auditing tool! :)

FlexPMD is a tool that helps to improve code quality by auditing any AS3/Flex source directory and detecting common bad practices

Would be interesting to start using this.

Gotcha:
The PMD Violations Viewer only accepts files that are named "pmd.xml", all other files will not be recognized. I run an Ant task to rename the generated pmd.xml to pmd_[insert timestamp here].xml. When I tried uploading the renamed file the PMD Violations Viewer wouldn't accept it. :(

Links: