Section 5.6. Publishing and Playing ActionScript Data


5.6. Publishing and Playing ActionScript Data

ActionScript data can be added to a published stream at any time. The data is always added as part of a method invocation request. For example, we can't just add the text string "Hi Robert, how are you?" to a stream. Instead, we have to name a method that will receive our text. In Example 5-1, we chose to have each client publishing an out_ns stream specify the method name "showMessage" and the text to pass to it:

 out_ns.send("showMessage", input_txt.text); 

The NetStream.send( ) method sends a method name, parameters, and timestamp to the server along with the published stream.

The out_ns.send( ) method invocation adds the name of the method ("showMessage"), the data to be passed into the method (the text from the input_txt.text field), and a stream timestamp to the published stream.

In the case of a live stream, the method name, parameters, and timestamp will be sent to the server along with any audio and video. The server forwards the ActionScript data on to any clients subscribed to the stream. When each client receives the ActionScript data from the server, nothing will happen unless the NetStream object playing the stream has a showMessage( ) method defined on it. From Example 5-1:

 in_ns.showMessage = function (msg) {   writeln(msg); }; 

Since the showMessage( ) method is usually invoked on a client other than the sender, it is referred to as a remote method .

Not only does the server send on ActionScript data to live subscribers of a stream, but it also stores the ActionScript data in the stream's FLV file if the stream is being recorded. Clients that subscribe to a recorded stream will also receive the recorded ActionScript data in sync with stream time and any audio or video that was recorded.

Sending ActionScript data in a stream can be tremendously useful. The data can be used to record all sorts of events, such as someone adding text to a chat, showing a slide during a presentation, or starting to publish a different stream.


Chapter 15 includes an entire session recording and playback framework based on recording and playing back ActionScript data in a stream. However, there are other ways to send a remote method request to other clients that are often more practical than sending data in a stream. Chapter 9 covers all the options for invoking remote methods in detail.

The client-side NetStream.send( ) method and the server-side Stream.send( ) method both allow you to send ActionScript data in a stream. There are two essential steps to making remote method invocation work: defining a method on the subscribing NetStream object and sending the request to the method within a published stream.

5.6.1. Defining a Remote Method

Defining a remote method to be executed on a NetStream object is no different than defining a method on any ActionScript object. The method can be defined on NetStream.prototype , which makes it available to every NetStream object, or as an individual method of a particular NetStream instance. The following code snippet shows two simple method definitions. Both methods rely on a function or object (not shown) to do the real work:

 // Defining a method on the   prototype   object for all instances. NetStream.prototype.showMessage = function (msg) {   writeln(msg); }; ns = new NetStream(nc); // Defining a method for a single instance. ns.doCommand = function (command) {   commandHandler.doCommand(command); }; 

Both methods can be invoked only if the NetStream object ns is playing a stream. Publishing streams cannot invoke their own methods using send( ) . When a NetStream method such as showMessage( ) or doCommand( ) is invoked, it cannot return a value the way a normal ActionScript function can. If a remote method does attempt to use a return statement to return a value, the value is discarded.

5.6.2. Sending a Request

A request to invoke a remote method can be sent by a publishing NetStream object or by a subscribed server-side Stream object. Both objects use the send( ) method to make a request. The first parameter of the send( ) method is always the name of the remote method (handler name) to invoke. Any optional parameters passed after the method name are passed as parameters into the remote method when it is invoked:

 // Passing a single string parameter. out_ns.send("showMessage", input_txt.text); // Passing a complex object. cObj = {command: "rewriteField", text: "Sample Text.", scroll: 1}; out_ns.send("doCommand", cObj); 

On the server, method invocation requests can also be made by a Stream object:

 s = Stream.get("monitorStream"); s.send("showMessage", "New client logged in from " + client.ip); 

5.6.2.1 Stream logs

The send( ) method can be used to write log data into a recorded stream file. In fact, this is the way FlashCom stores all its log files.

The advantage to using streams to store log data is that streams, unlike shared objects, can store very large amounts of data with little impact on client or server memory.


The data can be read back by defining a method on a NetStream object and then playing the stream.

In the simple homegrown Example 5-15, a server-side Stream object is used to record events as they occur.

Example 5-15. Simple application logging
 log_s = Stream.get("log"); log_s.record("append"); application.onAppStart = function ( ) {   log_s.send("onLog", {event: "onAppStart",                        time: new Date( ),                        appInstance: application.name}); }; application.onConnect = function (client, userName, password) {   log_s.send("onLog", {event: "onConnect",                        time:  new Date( ),                        ip:    client.ip,                        userName: userName});   return true; }; application.onDisconnect = function (client) {   log_s.send("onLog", {event: "onDisconnect",                        time:  new Date( ),                        ip:    client.ip,                        userName: userName});   return true; }; 

Playing the log file back from a remote client is done by connecting to the instance and then playing the log stream. However, since this is a log file that may have taken many hours to record, we don't want to wait for hours to get back all the ActionScript data. To play all the ActionScript data immediately, we can set the flushPlaylists parameter to a value of 2 or 3:

 ns = new NetStream(nc); ns.onLog = function (info) {   for (var p in info) {     trace(p + ": " + info[p]);   } }; ns.play("log", 0, -1, 3); 

In this example, the value 3 is specified as the NetStream.play( ) method's flushPlaylists parameter. If a value of 2 or 3 is passed in, all remote method call requests are retrieved immediately before any stream audio or video begins to play. A value of 3 resets the playlist while a value of 2 maintains the current playlist.

Here is some sample output:

 time: Sat May 24 22:42:51 GMT-0400 2003 event: onAppStart appInstance: customLog/_definst_ userName: Guest time: Sat May 24 22:42:51 GMT-0400 2003 ip: 127.0.0.1 event: onConnect userName: blesser time: Sat May 24 22:43:04 GMT-0400 2003 ip: 127.0.0.1 event: onDisconnect 

In fact, you don't have to go to all this work to log events. FlashCom can write out trace( ) messages to an application log for you if you ask it to. The messages are saved in a stream file as onLogMsg( ) requests and can be read back with a utility such as the one cited shortly. To turn on application logging, use the <RecordAppLog> tag in any Application.xml file. Replace the default false value with true :

 <RecordAppLog>true</RecordAppLog> 

Logging can use a great deal of disk space, so you may want to place individual Application.xml files with the <RecordAppLog> tag set to true in the home directory of the applications you want to log. The log file will be saved to the .../admin/streams/logs/application/ appName directory and will be named after the application instance name, for example, _definst_.flv . FlashCom can also create a server access log that records information about when users logged in and out of the system.

A utility to read log files and more information on FlashCom logs are available at:

http://www.macromedia.com/support/flashcom/ts/documents/flashcom_logging.htm

See Chapter 12 for another approach to application-level logging and Chapter 18 for a discussion of logging options.

5.6.2.2 Sending and recording events

The send( ) method can be used to send and record information to be acted on in sync with audio and video. For example, during an online lecture, a professor may wish to bold a section of text in a text field in order to focus attention on it. When the professor clicks a Send button, each student will see the section of text bolded in the Flash movie she is watching. Later, when the recorded version of the stream is played back, the bolding of text will again occur, synchronized to the audio stream of the professor's voice.

Making a system like this work requires building a Flash movie or movies that capture audio and events from the professor, translate the events into some form of data, such as an object, and send them in the stream. When the data in the stream arrives at the subscribing movie, it must be acted on to produce the required effect.

When an object is used to send an instructionfor example to tell another movie to bold text in a text fieldit is often called a command object . See the Command design pattern in the book Design Patterns by Erich Gamma et al. (Addison Wesley).

Example 5-16 shows a partial listing of code that creates an object containing information about the formatting of text in a text field. (The complete example is available on the book's web site.) The formatTextCommand object is an instance of the FormatTextCommandClass class and contains the starting and ending positions of the text to select and bold. It is created after the user highlights some text and clicks a Send button.

Example 5-16. Sending a command to set selected text in bold
 function FormatTextCommandClass (start, end) {   this.startIndex = start;       // Beginning of selection   this.endIndex = end;           // End of selection } FormatTextCommandClass.prototype.destination = "code_mc"; FormatTextCommandClass.prototype.command = "formatText"; FormatTextCommandClass.prototype.repaint = false; // Called when the Send button is clicked. function doSend ( ) {   if (lastTextobj.focusedField == code_txt) {     // Show the professor the text set in bold.     code_txt.setTextFormat(normalFormat);     code_txt.setTextFormat(lastTextObj.startIndex,                            lastTextObj.endIndex,                            highlightFormat);     // Create a command object and queue it up.     var formatTextCommand = new FormatTextCommandClass(lastTextObj.startIndex,                                                        lastTextObj.endIndex);     sender.queueCommand(formatTextCommand);   }   sender.send( ); } 

The lastTextObj and sender objects are not shown. The sender object contains a queue of events and sends them in a stream using the following statement (where obj is a command already in the sender's queue):

 ns.send("doCommand", obj); 

When the stream is playing (live or recorded), command objects are passed into the doCommand( ) method of subscribing streams:

 ns.doCommand = function (command) {   command.time = this.time;   commandHandler.doCommand(command); }; 

In this case, the commandHandler object passes the command on to an object that finds the destination movie clip (in this case named code_mc ) and calls its formatText( ) method. The formatText( ) method, shown in Example 5-17, sets the formatting of the code_txt field and then uses the information in the command to bold a section of the text.

Example 5-17. Processing the command to bold a text selection
 highlightFormat = new TextFormat(  ); highlightFormat.bold = true; highlightFormat.color = 0x004433; normalFormat = new TextFormat( ); normalFormat.bold = false; normalFormat.color = 0x006655; function formatText (command) {   code_txt.setTextFormat(normalFormat);   code_txt.setTextFormat(command.startIndex, command.endIndex, highlightFormat); } 



Programming Flash Communication Server
Programming Flash Communication Server
ISBN: 0596005040
EAN: 2147483647
Year: 2003
Pages: 203

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net