There are a few fundamental concepts to understand about FCS before beginning.
FCS applications are written in Actionscript 1.5.
Download Actionscript 1.5 Server-Side Communication Dictionary (PDF, 1.3MB)
FCS has several distinct facilities designed to push data to a client.
A remote shared object is an object stored on FCS. When clients connect to a remote shared object, they receive a copy of the object’s properties and subsequently receive any updates to the object made either by the server or by other clients. Use remote shared objects to share information, maintain state, and push changes to clients.
A remote shared object can contain methods and properties. When a method of a remote shared object is called, it is executed on every client connected to the shared object. This provides a very useful way to push application changes and configuration to a client.
Like remote shared object methods, client object methods also reside on the client and are executed by FCS. Unlike the method of a shared object, client methods can be executed on a single client or groups of clients.
All three of these schemes are used at different times throughout complex applications. The first, remote shared object updates, is probably the most common and is the first scheme explored in the following examples.
The Virtual Horse Race application requires both a server and client component. You start by building the server application. I review the source code in horse_race_01.asc file below (this file is in the ZIP file in the Requirements section). To set up the file, use the following steps.
The code below defines an application on FCS. It creates a new shared object named horseData and adds five additional objects to horseData, each representing a horse in the race. Every two seconds, the horse moves a random number of pixels forward, until one horse wins. Once a horse wins, the race restarts.
Take a moment to look through the horse_race_01.asc file and read the comments.
//This function is called as soon as the first client connects or the application is started through any means
application.onAppStart = function()
{
//Using SharedObject.get, we obtain a reference to our shared object
horseData_so = SharedObject.get("horseData");
//I call a function to setup our race params and reset everything to default
//This function is unrelated to FCS operations and is specific to our horse race application
application.resetRace();
//I setup an interval, to call our moveHorse function every 2 seconds
horse_change_interval = setInterval(application.moveHorse,2000, this);
}
application.onAppStop = function()
{
//This function is called when the application terminates
trace("onAppStop Called");
}
application.onConnect = function(clientObj)
{
//This function is called whenever a client attempts to connect
//I accept this connection.
application.acceptConnection(clientObj);
//I am going to allow our client to read anything, but at this point we are preventing write access
clientObj.readAccess = "/";
clientObj.writeAccess = "";
}
application.onDisconnect = function (clientObj)
{
//This function is called when a client disconnects
trace("*** onDisconnect called.");
}
/* ****************************************************** */
application.resetRace = function()
{
for ( var i=0; i<5; i++ )
{
//I am going to create/set 5 properties in our shared object.
//named 0,1,2,3,4
//Each of these properties is going to contain a label, an image, and a position
horseData_so.setProperty( i, { label:"Horse "+i, image:"horse_"+i+".jpg", position:80 } );
}
}
application.moveHorse = function()
{
//This is a very basic function put together in a basic way to illustrate continually changing data
//Race won is a flag indicating a horse passed the finish line
var race_won = false;
//Finish line is a variable indicating the end of the race. It corresponds to a pixel position in the flex app
//In a good application, this would not be hardcoded, but might be in a database or derived from the client
var finish_line = 549;
//clear our interval and prevent this function from being called again until we are ready
clearInterval(horse_change_interval);
trace("Moving Horses");
//I am preventing FCS from sending any updates to the client until we unlock this shared object
horseData_so.lock();
//I save data into five different properties in our shared object.
//Each property contains another object with three properties, a label, an image and a position
//The label and image will stay constant, however, the position will change, incremented by a random number every time
for ( var i=0; i<5; i++ )
{
//I retrieve the property named i [0..4] from our shared object
var currentObj = horseData_so.getProperty( i );
//I increment only the position by a new random number
currentObj.position = currentObj.position + Math.floor( Math.random()*25 );
if ( currentObj.position > finish_line )
{
//The race was won
race_won = true;
break;
}
//I set the property in our shared object with the new information
horseData_so.setProperty(i, currentObj );
}
//Our horses never quit. If they win, they just start over
if ( race_won )
application.resetRace();
//Unlock the shared object, this allows FCS to send the results to the client
horseData_so.unlock();
trace("Reset Interval");
//Setup an interval so we can do this all again in 2 seconds.
horse_change_interval = setInterval(application.moveHorse,2000, this);
}
There are a handful of critical lines in horse_race_01.asc that warrant further examination.
horseData_so = SharedObject.get("horseData");
This line causes FCS to obtain a reference to horseData, the name of the shared object. Without this line, FCS cannot read or write the shared object, preventing it from sending updates to connected clients.
horseData_so.lock();
FCS sends updates to clients at regular intervals. However, there are times when you may update hundreds or thousands of records at once. In this case, it’s better to prevent FCS from sending multiple updates and instead create one larger update. Locking the shared object prevents FCS from sending updates until it is unlocked.
horseData_so.unlock();
Unlocking a shared object allows FCS to resume normal operation and send updates to the client applications.
var currentObj = horseData_so.getProperty( i ); horseData_so.setProperty(i, currentObj );
FCS does not access properties of a shared object directly; it uses two accessor functions to provide read and write access. The getProperty function reads a property and setProperty function writes a property.