Building a Simple Flex 2/FMS 2 Test Application

A lot has changed with the introduction of ActionScript 3. For example the NetConnection class is now an event broadcaster (the onStatus method is gone) and a new Action Message Format (AMF) has been introduced to enable efficiently sending bitmap and other data over a NetConnection. To make things more complex, Flex 2 may be an entirely unfamiliar working environment for many used to working in Flash. This short article is designed to describe a few of the changes as well as provide the source code for a very simple Flex 2/FMS 2 test application. The application is provided as a Flex 2 zip archive so that you can import it as a project into Flex 2 or simply extract the files and look at them with a text editor. The application shows how you can use Flex 2 and AS3 to:

The sample does not show how to use remote shared objects. For a more elaborate sample that shows how to use shared objects, control a live stream, build a shared rich text editor, text chat, video conference and other things, see the Flex 2 FMS Explorer.

Note: This technote was originally written for Flex 2 beta 1 and was only recently updated:

  1. April 23/06 to work with Flex 2 Beta 2 thanks to Wade Roberts who was kind enough to send me updated code. If you have the beta 1 code you should download the most recent version of the zip file for beta 2.
  2. May 9/06 to work with Flex 2 Beta 3.

Before describing the changes and how the code works here is the zip archive file: flex2FMS.zip.

The archive contains a main.asc file you should place in a flex2FMS folder in you applications directory.

To install and run the application within Flex 2, start Flex and select File > Import > Existing Projects into Workspace. Choose Select Archive File, and import the zip archive. You should see a project named flex2FMS you can run.

Some Changes

When you look at the application code it may look unfamiliar at first so I'll start by describing some of the changes from AS1/2 to AS3 you should be looking for. I already mentioned that the NetConnection class has changed.

NetConnection Class Changes

In ActionScript 1 and 2 we were used to doing this sort of thing:

nc = new NetConnection();
nc.onStatus = function(info){
   trace(info.code);
   // lots more code here to deal with connection events...
}
nc.connect('rtmp:/myApplication');

If you try code like that in Flex 2 you'll get an error like this:

Access of possibly undefined property 'onStatus' through a reference with static type 'flash.net:NetConnection'

If you try to use an AS2 workaround like this:

nc = new NetConnection();
nc["onStatus"] = function(info){
   trace(info.code);
   // lots more code here...
}
nc.connect('rtmp:/myApplication');

you'll get this error at runtime:

Cannot create property onStatus on flash.net.NetConnection

So how do you get notifications of connection events? You write code something like this:

// Current release of FMS only understands AMF0 so tell Flex to 
// use AMF0 for all NetConnection objects.
NetConnection.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0;



private function init():void{
	// Create the NetConnection and listen for NetStatusEvent and SecurityErrorEvent events
	nc = new NetConnection();
	nc.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
	nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, netSecurityError);
	nc.connect("rtmp:/myApplication");
}

private function netStatus(event:NetStatusEvent):void {
	trace("netStatus: " + event);
	var info:Object = event.info;
	trace(info.code);
	// lots more code here...        
}

private function netSecurityError(event:SecurityErrorEvent):void {
	trace("netSecurityError: " + event);
}

There are at least three things worth pointing out about this code. First, Flex 2 uses a newer, more powerful, and incompatible version of Action Message Format (AMF) to send ActionScript data over a NetConnection. The new AMF3 will allow you to send things like bitmaps whereas AMF0 did not. The current version of Flash Media Server (FMS 2.0) does not use the newer AMF3. Fortunately, you can tell the NetConnection class to use the older AMF format when sending ActionScript data this way:

NetConnection.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0; 

Second, the onStatus handler has been replaced with the NetStatusEvent. To receive NetStatusEvents an object must register itself as a listener for them. This line, taken from within a class method, makes sure the method named netStatus is called whenever a NetStatusEvent occurs:

nc.addEventListener(NetStatusEvent.NET_STATUS, netStatus); 

When the netStatus method is called it is not directly passed an information object as in the past. Instead it is passed an event with an info property. The info property is the information object we're all used to:

private function netStatus(event:NetStatusEvent):void {
	var info:Object = event.info;
	trace(info.code);       
}

NetStream and Video Class Changes

The NetStream and Video classes have changed as well. For example the NetStream class now broadcasts a netStatus event instead of having a onStatus method and the Video class has a new method, attachCamera, to attach a video stream from a camera object. As you work with all the communication classes you should check both the AS2 to AS3 Migration page and the Live Docs. The biggest change is that the NetStream class is no longer dynamic. So you can't do something like this:

inStream.showMessage = function (msg:String):void{ // NOT ALLOWED!!!!
   writeln("showMessage: " + msg + "\n");
}

Instead the NetStream class has a new property named client that you can set. The method of the client object are called instead:

inStream.client = this; 

In the short sample provided here, this refers to the application object that has a public method named showMessage defined this way:

public function showMessage(msg:String):void{
   writeln("showMessage: " + msg + "\n");
}
Note: the method must be public.

Working in Flex 2

Working in Flex 2, if you're used to Flash, can be a challenge at first. There's a lot to learn. Fortunately the documentation on the http://labs.macromedia.com site and that ships with Flex 2 is remarkably good - especially for a beta. The documents (at least during the beta) can be found on the labs site. However, after experimenting with Flex 2 and building a basic user interface I couldn't find a simple Video object to drop on the stage. There is a VideoDisplay component but it doesn't have an attachCamera method. So here is what I did:

  1. Created a new UIComponent I called videoHolder;
  2. Created two Video objects named localVideo and returnedVideo;
  3. Added the video objects to the videoHolder component (using addChild);
  4. Added the videoHolder to a component on the stage.

Here's the bit of code that does that:

var videoHolder:UIComponent = new UIComponent();
videoHolder.setActualSize(320, 120);
						
localVideo = new Video(160, 120);
videoHolder.addChild(localVideo);
localVideo.x = 0;
localVideo.y = 0;
			
returnedVideo = new Video(160, 120);
videoHolder.addChild(returnedVideo);
returnedVideo.x = 160;
returnedVideo.y = 0;
			
videoHBox.addChild(videoHolder);

The Flex 2 application itself is a very simple one. The MXML that describes the user interface is at the top of the flex2FMS.mxml file. Within the UI markup you'll find a little code you should be aware of. First and easiest to miss is the call to the init() function in the application tag:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
                layout="vertical" 
				   creationComplete="init()">

The part in bold guarantees that after all the UI elements in the application have been created the init() function will be called.

The other code is within the Button tags. For example the connect() method is called with the connectButton is pressed:

<mx:Button label="Connect" id="connectButton" click="connect();"  width="100"/> 

The rest of the code is inside one script tag and is heavily commented.

Here's a link to the zip archive again.

Credits

The sample application provided here is based on AS3 code that David Simmons, who works on the FMS team in Adobe, was kind enough to send me. Thanks David! Also, Wade Roberts provided a corrected version of the code for Flex 2 beta 2. Thanks Wade - that was totally unexpected and much appreciated!


Document posted February 2, 2006 by Brian Lesser
Source code updated for Flex 2 Beta 2 April 23, 2006 by Brian Lesser from code supplied by Wade Roberts. Corrections included:

  1. changed the xmlns tag to point to adobe (http://www.adobe.com/2006/mxml)
  2. separated the two video windows by 10 pixels for clarity's sake
  3. removed references to 'undefined' so the AS3 compiler doesn't complain
  4. updated writeln function to use 'verticalScrollPosition' and 'maxVerticalScrollPosition'

Source code updated for Flex 2 Beta 3 May 9, 2006 by Brian Lesser. Corrections included:

  1. Removed this line: NetStream.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0; as it is no longer necessary to set the defaultObjectEncoding because the NetStream object automatically picks up the encoding of the NetConnection passed into its constructor.
  2. inStream.client = this used instead of dynamically attaching a method to the NetStream object itself.