The Shared Cursor is a great component to demonstrate synchronization using the Flash Communication Server. The concept is this: When data changes, everything connected to the application (with security) must respond to the change. That response is completely up to you. Macromedia has used the object framework to allow you ultimate flexibility in handling data change.
There are at least two relationships that you can achieve with synchronization. These forms relate to how you set up the application. A subscriber/publisher relationship can have two forms. A one-way format has no interaction. This is similar to a presentation or a TV-type show with no return channel to receive input from the remote players. Another format for this relationship is similar to a classroom model with a group of students and a teacher facilitating a discussion. The teacher controls time where the participation is a one-way discussion and times where students can interact (multiple-way). Both formats in this relationship usually have two separate Flash movies communicating with a common Server application instance. One Flash movie would have publishing controls built-in such as enabling NetStream publishing for video conferencing, or moderating discussion for a chat window. One very common approach is running a slide presentation, where one Flash movie has the capability to advance slides and publish an audio video stream, while a second (public) Flash movie cannot do anything but watch the presentation.
A collaborative relationship features a format where everyone connected can control everything. The previous exercise is a good example of that. Everyone was able to control the WhiteBoard yet maintained sole control of her mouse pointer. This form of communication is perfect for games or collaborative working environments. Socially, it requires the most diplomacy within a group, but that's a whole other chapter.
How does Flash Communication Server actually do the synchronization? The server treats each change of the SharedObject as an event. Within Flash MX, the SharedObject uses a new event handler, onSync. The .onSync event handler is triggered when the server announces a change to a SharedObject. In the case of the cursor component, your mouse movement writes the x,y values to the SharedObject. So, every time a mouse is moved, data on the server is changed, and the server announces that change to every Flash player that is connected, including the one that made the change.
The .onSync method is invoked by every Flash player when the server sends these announcements. Every connected Flash player receives an Information object containing an array of objects, each with three properties. The array length is equal to the number of data attributes that changed on the server. This architecture is what allows you to support "disconnected" clients, such as mobile devices, where connection times are short and intermittent. For example, when a mobile device connects to the server, it synchronizes itself using the .onSync event looping through the array of objects sent by the server.
Each object within the array only carries three parameters. These parameters describe the change to the data. They do not contain the data. It is up to you (using ActionScript) to review the objects and retrieve the data as they describe. The three parameters are code, name, and oldValue. These are important to understand, so let's get into some further detail.
The value of the code parameter is the controller. You base your actions on its value. There are five possible values that code can have:
Success This value is received by only the Flash client that successfully made the change to the SharedObject. When your application receives this request, usually you ignore it because the change was already made on your player, or you message the user that the update was successful. It is like resetting the cursor x,y values each time you move the mouse. It is not required.
Change This value is received by each Flash client that did not make the change to the server. You use this value challenge to invoke the changed property values to the Flash client.
Reject This value is received by only the Flash client that unsuccessfully tried to make a change to the SharedObject. This is usually the case when a collision happened, where two clients tried to write to the same property at the same time. If this happens, consider locking the SharedObject. This will be explained in Chapter 14, "Server Administration."
Clear This value is received by a Flash player that connected to a SharedObject for the first time. When using a temporary SharedObject, the SharedObject only persists as long as it is being used. This value can be used to invoke a process of initialization to create initial object structures and values on the server. Clear is also sent if the server and client data are so far out of sync that the client dumps its version of the SharedObject and resynchronizes itself completely.
Delete This value is returned to all Flash players when an object has been deleted.
The name value describes the name of data attribute (or slot) that was changed within the SharedObject. To access the data, ActionScript contacts the server to retrieve the value(s) of each changed data attribute. If the data attribute was an object, you must know the architecture of the object to retrieve the information. If the attribute was an array, you retrieve the entire array and resynchronize it with the local data. The data attribute can be any of the basic ActionScript or JavaScript types including strings, numbers, Boolean, arrays, or objects. It is in the data attribute that you must have a strategy planned for data storage. You do not want data on the server that you do not plan to share.
When the code property returns reject or change, this parameter contains the former value of the changed object. This allows you essentially to "override" the change and revert the attribute back to its previous value.
Warning
The onStatus event is not triggered if an identical value is written to a SharedObject data attribute. If you write a value of Hello World to an attribute that already contains the string "Hello World", onStatus does not run.