AS3 Adventures: Porting my FMS classes to Actionscript 3
Posted by Jay Charles | Filed under Flash Platform
I’ve been working with Flash Media Server since version 1 (when it was Flash Communication Server), and during that time, I’ve developed a fairly robust set of classes and components for rapid development of AS2/FMS applications.
Now that the majority of my clients are ready to cuddle up to the idea of requiring Flashplayer 9 (h.264 support in FP9 did a lot to help that), I’m working on porting out all of my code to Actionscript 3. I’ve been noodling with AS3 since Flash CS was released, but it’s just now that I’m finding the time (and the cause) to rewrite all of those thousands of lines of code. As work progresses, I’m finding a few interesting gotchas along the way, and I’ll update this blog post as I find and work through them. Hopefully, it will save other developers from a few time wasting sessions digging for a problem.
Gotcha - Can’t invoke methods or alter properties on a null camera device
If you’re used to Actionscript 2, then you feel perfectly confident invoking Camera.setMode() recklessly, even if you haven’t checked for the presence of a camera device. In AS3, you can’t do that. I’ve found that if you invoke a method or alter a property of a null camera object, code seems to stop running. For example:
var myCam:Camera = Camera.getCamera();
myCam.setMode(320,240,12);
If the user has a camera (or a device driver that fools the player into thinking there’s a camera somewhere), then code will continue to execute. If there is no camera device on the machine, code stops executing.
The solution here is to always test for a null value on the camera object before invoking any methods on the object:
var myCam:Camera = Camera.getCamera();
if(myCam != null){
myCam.setMode(320,240,12);
}
Gotcha - The onMetaData event isn’t part of the NetStatusEvent class
This one sort of bugs me a little. I absolutely love the event dispatcher structure of AS3, and developing custom handlers is a breeze, but for some reason onMetaData was left out of the NetStatusEvent class. I’m not sure why really, as onMetaData is [as I see things] pretty important to any video application.
Unless you want to rework the flash.net.NetStatusEvent class to include it (which I don’t recommend… but that’s for another discussion), the answer here is to use the client property of the NetStream class. You create an object, add your onMetaData method to the object, and then set the client property of the netStream to the object you just created. It’s all very Actionscript 2-esque:
var ns:NetStream = new NetStream();
var ns_client:Object = new Object();
ns_client.onMetaData = function(metaObject){
// handle meta events here. I like to run a call to my custom handler for the stream's NetStatus events so the rest of my app can use a single event listener.
}
ns.client = ns_client;
I don’t really understand why the onMeta event wasn’t included in the NetStreamEvent class… maybe in AS4?
Gotcha - You can’t invoke NetConnection.connect() from a netStatusEvent handler.
This is one really, really bugs me. Some of the FMS applications I develop are high volume with connection requests in the thousands per minute, and when I load balance, I often use an FMS application to handle the load balancing. For this reason, I tend to shy away from the “connection shotgun” approach for picking the port/protocol combination for the client (where the client makes simultaneous connection requests on all ports/protocols and uses the first one to succeed), as it would create potential for doubling or tripling the number of concurrent connection requests hitting the servers. For this reason, I prefer to make my connection attempts in sequence with a programatic timeout for each, trying RTMP on port 1935, then 80, and finally RTMPT over port 80… waiting for either a failed or rejected info code (or for the timeout to expire) before trying the next one
In Actionscript 2 I was able to handle NetConnection.Connect.Failed results in my onStatus handler for the NetConnection, but in AS3 you just can’t do that… even if the call to NetConnection.connect() resides in a function outside the netStatusEvent handler. For example…
function connectNC(){
my_netconnection.connect(blah, blah,blah);
}
function netStatusHandler(e:NetStatusEvent){
if(e.info.code == "NetConnection.Connect.Rejected" || e.info.code == "NetConnection.Connect.Failed"){
connectNC();
}
}
…results in this lovely runtime error:
#2132 NetConnection.connect cannot be called from a netStatus event handler.
I’m sure there’s some good reason for this, but I can’t help but think this is one of those “let’s prevent the novice from killing their server with connections” sort of decisions. I’m a big boy, and I think I can handle a little danger… so I wish I could have my cake here.
For the short term, my solution is to set up a timer to call the connect function from it’s handler in the NetConnection.Connect.[Failed/Rejected] event, and then run the timer down in one millisecond. It works fine, but it’s sort of hackish if you ask me. Anyone have a better/prettier solution for this? I’d love to hear it.
More gotchas to come as they find me.
October 3rd, 2008 at 2:34 am
Funny, I had this problem and as soon as saw your post I could fix it.
My problem was that I was calling NetConnection.connect from a netStatusHandler and I was getting the same error message.
In my netStatusHandler I was calling the connect function if the status was anything other than NetConnection.Connect.Success (I also have variables like RTMPConnectAttempts, RTMPTConnectAttempts
) but I found out that calling NetConnection.close() WILL call your netStatusHandler with an event.info.code set to NetConnection.Connect.Closed.
I had to ignore NetConnection.Connect.Closed in my netStatusHandler.

November 20th, 2008 at 11:07 pm
Hey Guy’s,
I used Flash Communication Server MX back in the day I’ve been trying to get back into things and can find any documentation for Flash Media Server? It’s as if the program is out there but noone uses it or hasn’t written a single tutorial?
Can you guys tell of any learning resource, tutorials books examples.
I do know Action Script 3 very well
Thanks
November 21st, 2008 at 9:49 am
If you were comfortable with FCS, the FMS should be no problem. While some new classes have been added, and the license structure has changed, FMS 3 is very much like FCS from a programming standpoint.
Some good resources (other than the docs) are:
http://flashcomguru.com
http://fmsguru.com
February 12th, 2009 at 5:08 am
Sorry for delayed response:)
We could use setTimeout function to avoid “#2132 NetConnection.connect cannot be called from a netStatus event handler.” error.
function netStatusHandler(e:NetStatusEvent){
if(e.info.code == “NetConnection.Connect.Rejected || e.info.code == “NetConnection.Connect.Failed){
setTimeout(connectNC, 100);
}
}
November 25th, 2009 at 10:38 am
Are you sure about the placement of the double quotes? Single only and just on the laft side of the statements? I get an error when I run this but when I put enclosing right quotes the code color indicators in AS3 go all flukey.
Thanks
November 25th, 2009 at 10:42 am
Ok - sorry - Be careful copying code directly from a web page - introduces some “wonky” characters - go through notepad or other simple text editor first (I shoulda remembered that :P)
Sorry and thanks
(everyone else - let that be a lesson to ya!)
November 30th, 2009 at 10:17 am
@Bobkatzz - Sorry about that… typo on my end. I corrected the code to include the closing quotes on those status strings. Thanks for pointing it out.