Wednesday, April 25, 2007

FMS - What I'm Learning about Client and Server Scripts

I have an MXML/AS3 component that calls some remote FMS1 methods, which works well. However, the client callbacks are not working.

Being an FMS newbie, I'm wondering if this is an AS2/AS3
2 issue. So, I turned to the O'Reilly book Programming Flash Communication Server to learn more.
In the pursuit of getting client callbacks to work, here is some of what I've learned about FMS and client scripting so far... 
Client-To-Server Calls
  • Each SWF that connects to FMS is called "The Client" and is referenced by the SSAS3 code via the "Client object."

  • Clients use the NetConnection.call(...) method to ask the server to do something for them. For the call to work the method on the server must have the same name and it must be attached to the server-side Client Object.
    For example...

    nc.call("getStreamLength", resultObject, name);

    - Where nc is the NetConnection object used to connect the client to FMS.
    - To process the results a handler method should to be defined.

  • Server-side methods must to be attached to the Client object to be invoked by a SWF (the Client).
    For example...

    // The new function object is attached to the client object
    // so that it can be called by the client.
    clientSWF.getStreamLength = function(name)
    {
      return Stream.length(name);
    };

  • SSAS also allows you to attach methods to the "Client.prototype" object4. This helps save memory and processor time on the server and every instance of that class (I.e. the Client class) will contain the attached methods automatically. For example...
    Client.prototype.getStreamLength = function (name)
    {
      return Stream.length(name);
    };

  • To sum up...
    • You can attach SSAS methods needed by every Client object to Client.prototype.
    • Alternatively, you can define SSAS methods on specific client instances. This is how you can allow access to specific SSAS methods for a subset of clients connected to the application.
Server-To-Server Call


  • For the server to call a client-side method, the method must be attached to a client-side NetConnection object.
    For example...

    nc.setStreamLength = function(value)
    {
       this.streamLength = value;
    };

This is where I think my problem is...
Somehow I have to attach my AS3 client-side method to the NetConnection object. But, the NetConnection object is a sealed class in AS3 (AS2 it is a dynamic class). So, I created a dynamic class (named "netConnect") that extends the NetConnection class and now I need to figure out the syntax to add an AS3 function object to a dynamic class.
(2007-04-25 - 3:30 PM CST)

The solution was pretty easy...
I just added a dynamic property to my netConnect class and then assigned my function statement to it.
(2007-04-25 - 5:26 PM CST)


Client-Side AS3:
/////////////////////////////////////////
private var nc:NetConnect = new NetConnect();
/////////////////////////////////////////
public function onCreationComplete():void
{


   var myTimer:Timer = new Timer(1000, 0);
   myTimer.addEventListener("timer", createConnection);
   myTimer.start();


}
/////////////////////////////////////////
private function createConnection():void
{
   if(!nc.connected)
   {
      nc.objectEncoding = flash.net.ObjectEncoding.AMF0;
      nc.connect("rtmp:/testCallback");       // Local FMS Application
      nc.update = callBack;                       // Assign callBack() function
      this.connect(nc);
      nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
   }
}

/////////////////////////////////////////
public function callBack():void
{

   trace( "** The callBack() function was called by the server **" );
}


Server-Side AS2:
...
clientSWF.call("update", null);
...
FMS - Flash Media Server
AS2/AS3 - ActionScript Ver. 2 or 3
SSAS - Server Side ActionScript
The "Client.prototype" object is the base class of the Client object

Friday, April 13, 2007

Multiple "effectEnd" events from a parallel effect

I created a parallel effect with AS3...

var zoom:Zoom = new Zoom();
zoom.easingFunction = Exponential.easeIn;
zoom.duration = 1500;
zoom.zoomHeightFrom = 0.0;
zoom.zoomHeightTo = 1.0;

var fade:Fade = new Fade();
fade.easingFunction = Exponential.easeIn;
fade.alphaFrom = 0;
fade.alphaTo = 1;
fade.duration = 1500;

msgEffect = new Parallel();
msgEffect.targets = effectsArray;
msgEffect.addChild(zoom);
msgEffect.addChild(fade);
msgEffect.play();
I added a listener for when the effect ends...

addEventListener(EffectEvent.EFFECT_END, close);
Then I coded the following handler...

private function close(event:EffectEvent=null):void
{
visible = false;
mx.managers.PopUpManager.removePopUp(this);
dispatchEvent(closeEvent);
}
Even though the effects are part of a parallel effect sequence object, two "effectEnd" events are fired one for the Zoom and the other for the Fade.

I believe this occurs because the targets fire the "effectEnd" event, not the parallel effect sequence object.

It looks like I need some wrapper that says, "Hey, both effects in your parallel effect sequence object are done!" Seems odd though, shouldn't the parallel sequence object do that?

Well, here's my very cheesy fix for this problem. I changed the event handler as follows...

private function close(event:EffectEvent=null):void
{
  visible = false;
  mx.managers.PopUpManager.removePopUp(this);
  dispatchEvent(closeEvent);
  // Ignore any other "effectEnd" events.
  removeEventListener(EffectEvent.EFFECT_END, close);
}

Wednesday, April 11, 2007

Fading buttons and embedded fonts

To apply a fade effect to text you must use embedded fonts. I was going nuts trying to use an embedded font with buttons so the applied fade effect would work. After several failed attempts I found this post (thanks Jesse!).

In short, create a style that looks like this...
Button
{

embedFonts: true;

fontWeight: normal;

fontSize: 22;

fontFamily: YourEmbeddedFont;

}