Flash Player Debugger on Ubuntu

After having spent a good part of an hour on trying to install the Flash Player Debugger for FireFox on Ubuntu 11 64-bit, I found the following steps worked:

  1. sudo apt-get install nspluginwrapper
  2. copy libflashplayer.so (from debugger download) to /usr/lib/flashplugin-installer/
  3. sudo nspluginwrapper -i /usr/lib/flashplugin-installer/libflashplayer.so
  4. restart FireFox

Thanks to: AskUbuntu.com.

Don’t forget to set up mm.cfg.

When all is done, run:

tail -f ~/.macromedia/Flash_Player/Logs/flashlog.txt

Alchemy on Windows7

Installing Adobe Alchemy on Windows7 wasn’t as straightforward as the Adobe Labs site made me believe.

The following error would keep on showing when I tried to run the example:

$ gcc stringecho.c -O3 -Wall -swc -o stringecho.swc
llvm-gcc.exe: error while loading shared libraries: ? …

I finally got it to work by using the steps below:

  1. Install the Alchemy Repack, from www.covergraph.com in a temporary directory (I just want to copy some of the files).
  2. Download and install Alchemy from the Adobe website, as per their instructions.
  3. Copy the “achacks”, “avm2-libc”, “bin” and “flashlibs” folders from your “Alchemy Repack” installation folder.
  4. Uninstall / Delete Alchemy Repack
  5. Good to go! 🙂
  6. (Optional:) Set the “CYGWIN=nodosfilewarning” environment variable option to avoid Cygwin warnings about MS-Dos style paths. (Unfortunately, this doesn’t work for me, even though “echo ${CYGWIN}” prints “nodosfilewarning”.)

Note: If you already have Cygwin installed, you can install additional packages by running setup.exe again.

Sound from ByteArray

While writing a quick test application to record microphone input and playing that same recording, I found out that playing back a ByteArray directly using the Sound class wasn’t possible. Luckily a solution is never far away when doing a Google search and it turns out that FlexibleFactory has a good solution: the MP3FileReferenceLoader lib. With a bit of tweaking you can pass in a ByteArray directly and don’t need to rely on a FileReference.

Good news though! As per Flash Player 11, the following 2 methods have been added to the (native) Sound class that can be used to achieve the same behaviour:

  • Sound.loadCompressedDataFromByteArray(bytes:ByteArray, bytesLength:uint)
  • Sound.loadPCMFromByteArray(bytes:ByteArray, samples:uint, format:String = “float”, stereo:Boolean = true, sampleRate:Number = 44100.0)

Flex FTP Abort

Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513 Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513 Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513 Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513 Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513

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:

  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:

  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:

  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.

  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:

  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?

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

Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513 Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513 Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513 Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513 Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513 Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513

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.

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

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

  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.

  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:

  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:

  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:

  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

Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513 Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513

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.

  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.

  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

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:

Flex IRC Client

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