Looking at the world of media: from music to RIA.

LocalConnection: Keeping strong types across applications

September 14th, 2007 Posted in ActionScript, Flash Player, Flex Development, Rich Internet Applications

flashlogo_grey.jpgI have been working on a project that requires the use of LocalConnections (LC) and one of the things I found out was that by default the LC does not retain the Class type when communicating across the bridge. After doing a little reading, I found out that the LC uses the AMF protocol for communication and serializes the object down to a base object that is then deserialized when received by the listening app. Honestly I wasn’t that surprised that the Class type was lost and it was easy enough to ignore for what I was working on. The problem is that this kind of thing often gets under my skin and I end up having to find out more about how it works and how I can make it do what I want.

A while back I was reading Darron Schall’s blog about the using of the [Transient] metatag and how it can be used for serialization and deep object cloning. The thing that kept jabbing my mind is that he quoted the Flex docs and said that this works with any AMF system, including LocalConnection. The more I thought about it the more his post made me think that what I wanted was possible… I could retain Class typing across the LC bridge, but how? As with most problems I fired up a test project and what started out as a simple question turned into a Utility class that is way, way more robust then I ever expected to write in a single hack-a-thon.

First off, let me quickly talk about the solution and then I will jump into the details about the example code and Utility that I have written. Darron’s article was exactly the catalyst I needed and lead me down the path to registerClassAlias(). This is the key to keeping the Class types. What it does (from what I can tell) is register the class path to the class type so that when serialization happens the class path is stored as metadata in the serialized object. When the item is then deserialized the class path can be extracted and then the object is casted to the proper base Class.

Sounds simple enough, but as Darron (and many other people pointed out) the documentation on how to really use it is pretty lacking. What I found out is that you must call this before you serialize AND you must call this before you deserialize. The only problem is that by the time your method on the receiving application gets the data via the LC it has already been deserialized. This means that you have to register the class on the receiving end before the data is sent. The brute force way to do this is to know what methods you want to expose and what types they expect and then register the classes on both side before you start the LC communication. This is hardly elegant and this lead me down the Utility path.

Now that you know the answer, here is how I went about solving it. The first issue I have with LCs are that if you don’t set them up correctly you can enter a world of hurt. I know, because I stumbled on one of the nastier bugs. It appears that if you improperly handle the async event and then your browser hangs the LC gets stuck in memory and you have to restart you OS. Yup, not just your browser but your whole OS.

That experience sucked. I wanted to prevent this from happening to me ever again so I built a wrapper class that automatically handles the event management, sets the client, domain, target and connection name all for me right off the bat. The next thing I wanted it to do was create a single two-way communication protocol for the LC enabled apps so that errors that occur in one client inform the sending client that something went amiss. Finally (and most importantly) I wanted the Util to handle type registration when I send the message so that I don’t have to think about it. All I needed to know was the application client name, the method, the argument count and their types.

So, I here it is… the LocalConnectionManager, simple to use and hopefully is relatively bug free for a 0.1 release:

// example usage
// create an instance
var lcm:LocalConnectionManager = new LocalConnectionManager(this, "myApp1");
 
// register events
lcm.addEventListener(LocalConnectionEvent.CONNECTION_ERROR, handleConnectionEvent);
...
 
// call methods
lcm.sendMessage("targetClientName", "targetMethodName", myCustomClass);

Pretty simple, I hope. I have created a ZIP with full source under MPL 1.1 and two demo Flex apps that use the LCM. If you find issues or want new features by all means contact me and I am considering putting this on GoogleCode if people find it helpful, so let me know!!

folder.png Source and examples [download]

  1. 1 Trackback(s)

  2. May 22, 2008: Vivisecting Media » Blog Archive » Vivisecting Media Code Depot launched…

You must be logged in to post a comment.