More Books
Flash Communication Server
Flash Communication Server
Table of Contents
Copyright
About the Authors
Brian Lesser
Giacomo
Joey Lott
Robert Reinhardt
Justin Watkins
Foreword
Preface
What Does FlashCom Offer?
What's in This Book?
How to Use This Book
Audience
ActionScript 1.0 Versus ActionScript 2.0
Server-Side ActionScript
The flash-communications.net Site
Director, Breeze, and Other Options
Flash Video Options
Licensing and Hosting Options
Conventions Used in This Book
Voice
Using Code Examples
Safari Enabled
Comments and Questions
Acknowledgments
Part I:  FlashCom Foundation
Chapter 1.  Introducing the Flash Communication Server
Section 1.1.  Clients and Servers
Section 1.2.  Creating an Application
Section 1.3.  Real-Time Messaging Protocol
Section 1.4.  The Communication Classes
Section 1.5.  Communicating with Application Servers, Databases, and Directory Servers
Section 1.6.  Firewalls and Security
Section 1.7.  Getting Started
Section 1.8.  Hello Video!
Section 1.9.  Conclusion
Chapter 2.  Communication Components
Section 2.1.  Overview of Communication Components
Section 2.2.  Summary of Communication Components
Section 2.3.  Creating an Application that Monitorsa Connection
Section 2.4.  Building a Simple Chat Room
Section 2.5.  Adding Audio and Video to the Chat Room
Section 2.6.  Forgoing the SimpleConnect Component
Section 2.7.  Conclusion
Chapter 3.  Managing Connections
Section 3.1.  Making a Connection
Section 3.2.  Managing a Connection
Section 3.3.  Reusing a NetConnection Object
Section 3.4.  Multiple Simultaneous NetConnection Objects
Section 3.5.  Testing and Debugging Network Connections
Section 3.6.  Subclassing the NetConnection Class
Section 3.7.  Communication Components Without SimpleConnect
Section 3.8.  Conclusion
Chapter 4.  Applications, Instances, and Server-Side ActionScript
Section 4.1.  Scripting Application Instances
Section 4.2.  Differences Between Flash ActionScript and Server-Side ActionScript
Section 4.3.  The Life of an Application Instance
Section 4.4.  Running a Simple Hello World Test Script
Section 4.5.  A More Realistic Example
Section 4.6.  Instance-to-Instance Communications
Section 4.7.  Script Filenames and Locations in Detail
Section 4.8.  Testing and Debugging Server-SideScript Files
Section 4.9.  Designing Communication Applications
Section 4.10.  Conclusion
Part II:  Audio, Video, and Data Streams
Chapter 5.  Managing Streams
Section 5.1.  A Simple Publisher/Subscriber Example
Section 5.2.  Stream Names
Section 5.3.  Publishing Streams in Detail
Section 5.4.  Playing Streams in Detail
Section 5.5.  The Stream Class
Section 5.6.  Publishing and Playing ActionScript Data
Section 5.7.  Creating Synchronized Presentations
Section 5.8.  The NetStream and Stream Information Objects
Section 5.9.  Stream Enhancements and Limitations
Section 5.10.  Conclusion
Chapter 6.  Microphone and Camera
Section 6.1.  Working with Microphone/Audio Input
Section 6.2.  Working with Camera Input
Section 6.3.  Building a Message-Taking Application
Section 6.4.  Building a Surveillance Application
Section 6.5.  Conclusion
Chapter 7.  Media Preparation and Delivery
Section 7.1.  Audio and Video Compression
Section 7.2.  Converting Prerecorded Materialto FLV Format
Section 7.3.  Using Flash Pro's Media Components
Section 7.4.  Enabling Multiple Bit Rate FLVsWithin an Application
Section 7.5.  Streaming MP3 Audio
Section 7.6.  Conclusion
Part III:  Remote Connectivity and Communication
Chapter 8.  Shared Objects
Section 8.1.  Objects and Shared Objects
Section 8.2.  Getting a Shared Object in Flash
Section 8.3.  Updates and Frame Rates
Section 8.4.  Scripting Shared Objects on the Server
Section 8.5.  Temporary and Persistent Shared Objects
Section 8.6.  Proxied Shared Objects
Section 8.7.  Shared Objects and Custom Classes
Section 8.8.  Avoiding Collisions
Section 8.9.  Optimizing Shared Object Performance
Section 8.10.  Broadcasting Remote Method Callswith send( )
Section 8.11.  A Simple Video and Text Chat Application
Section 8.12.  Conclusion
Chapter 9.  Remote Methods
Section 9.1.  Why Use Calls?
Section 9.2.  The send( ) and call( ) Methods
Section 9.3.  Client-to-Server Calls
Section 9.4.  Server-to-Client Calls
Section 9.5.  Server-to-Server Calls
Section 9.6.  A Simple Lobby/Rooms Application
Section 9.7.  Debugging Calls
Section 9.8.  Advanced Topics
Section 9.9.  Conclusion
Chapter 10.  Server Management API
Section 10.1.  Connecting to the Admin Service
Section 10.2.  Using the Server Management API
Section 10.3.  Server Management API Uses
Section 10.4.  Conclusion
Chapter 11.  Flash Remoting
Section 11.1.  The Remoting Gateway
Section 11.2.  Remoting Basics
Section 11.3.  Role of Remoting in FlashCom Applications
Section 11.4.  Securing Access
Section 11.5.  Conclusion
Chapter 12.  ColdFusion MX and FlashCom
Section 12.1.  Understanding ColdFusion MXand Flash Remoting
Section 12.2.  Using Flash Remoting to Log Events
Section 12.3.  Getting a List of Streams
Section 12.4.  Using ColdFusion and FTP to Mirror Streams
Section 12.5.  Conclusion
Part IV:  Design and Deployment
Chapter 13.  Building Communication Components
Section 13.1.  Source Files
Section 13.2.  People Lists
Section 13.3.  A Simple People List
Section 13.4.  Listenable Shared Objects
Section 13.5.  Status and People List
Section 13.6.  Text Chat
Section 13.7.  Shared Text
Section 13.8.  Video Conference and Video Window
Section 13.9.  PeopleGrid
Section 13.10.  Summary
Section 13.11.  Conclusion
Chapter 14.  Understanding the Macromedia Component Framework
Section 14.1.  The Component Framework
Section 14.2.  Under the Hood of the Chat Component
Section 14.3.  Creating a Simple Component from Scratch: SharedTextInput
Section 14.4.  Creating a Container Component: SharedAddressForm
Section 14.5.  Creating an Authenticating Component
Section 14.6.  Integrating Components with Your Existing Applications
Section 14.7.  Understanding the Framework
Section 14.8.  Conclusion
Chapter 15.  Application Design Patterns and Best Practices
Section 15.1.  Shared Object Management
Section 15.2.  Moving Code to the Server
Section 15.3.  Building Façades on the Server
Section 15.4.  Server-Side Client Queues
Section 15.5.  A Framework for Recording and Playing Back Componentized Applications
Section 15.6.  Components and Component Frameworks
Section 15.7.  Conclusion
Chapter 16.  Building Scalable Applications
Section 16.1.  Coordinating Instances
Section 16.2.  Scalability and Load Balancing
Section 16.3.  Conclusion
Chapter 17.  Network Performance, Latency,and Concurrency
Section 17.1.  Latency
Section 17.2.  Bandwidth
Section 17.3.  Concurrency
Section 17.4.  Conclusion
Chapter 18.  Securing Applications
Section 18.1.  The Three A's: Authentication, Authorization, and Accounting
Section 18.2.  Authentication
Section 18.3.  Authorization
Section 18.4.  Accounting
Section 18.5.  Suggestions and References
Section 18.6.  Conclusion
Index
SYMBOL
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
R
S
T
U
V
W

4.4. Running a Simple Hello World Test Script

A typical helloWorld test program is usually the smallest test program that produces output on the screen. While server-side programs don't normally output anything directly to the user, a simple helloWorld example is still useful. In SSAS, the trace( ) function outputs text messages to the NetConnection Debugger, App Inspector, and log files on the server. During development, the App Inspector is the primary tool that allows developers to load, unload, and reload applications after a change is made in a script and needs to be tested.

Example 4-2 shows a short main.asc script that is the SSAS implementation of helloWorld. It demonstrates all the standard event handler methods of the application object.

Example 4-2. A simple server-side helloWorld test script
application.onAppStart = function (  ) {
   trace("onAppStart> " + application.name + " is starting at " + new Date( ));
};

application.onStatus = function (info) {
   trace("onStatus> info.level: " + info.level + ", info.code: " + info.code);
   trace("onStatus> info.description: " + info.description);
   trace("onStatus> info.details: " + info.details);
};

application.onConnect = function (client, userName, password) {
   client.userName = userName;
   client.writeAccess = "/public";
   client.readAccess  = "/";
   application.acceptConnection(client);
   trace("onConnect> client.ip: " + client.ip);
   trace("onConnect> client.agent: " + client.agent);
   trace("onConnect> client.referrer: " + client.referrer);
   trace("onConnect> client.protocol: " + client.protocol);
};

application.onDisconnect = function (client) {
   trace("onDisconnect> client.userName: " + client.userName)
   trace("onDisconnect> disconnecting at: " + new Date( ));
};

application.onAppStop = function (info) {
   trace("onAppStop> application.name: " + application.name);
   trace("onAppStop> stopping at " + new Date( ));
   trace("onAppStop> info.level: " + info.level);
   trace("onAppStop> info.code: " + info.code);
   trace("onAppStop> info.description: " + info.description);
};

With this example code in mind, let's take a closer look at the most important event handling methods of the application object. These are invoked automatically when the application starts, when a client attempts to connect, when a client disconnects, or when the application is supposed to shut down.

4.4.1. application.onAppStart( )

When an application instance is accessed the first time, the script is compiled and any global code (i.e., code outside the context of an event handler) is executed. After that, the application.onAppStart( ) method is called. In Example 4-2, the application.name property is used to output the name of the instance that has been started. The name will always be in the format appName/instanceName. For example, "helloWorld/_definst_" is the default instance name for the helloWorld application. If an instance name includes directories, the name property may contain a string such as "courseChat/chem101/room1".

4.4.2. application.onStatus( )

The application.onStatus( ) method receives messages for server-side Stream and NetConnection objects that do not have onStatus( ) handlers, in addition to other application messages. The onStatus( ) handler is not invoked in Example 4-2, but the handler declaration is included to show the information object properties that can be received.

4.4.3. application.onConnect( )

The application.onConnect( ) method shows the interaction between the application object and the client object passed into it. The client object is an instance of the Client class, which provides information about the Flash movie attempting a connection, such as its IP address. An instance of the Client class is always passed into the onConnect( ) method. In this example, each instance is named client. The difference in capitalization means that there is no name conflict between the Client class name and the individual client object passed into onConnect( ). If you find this confusing or want to use a naming convention that is consistent with how you write code in Flash MX, then instead of using client as an object name, use something like newClient:

application.onConnect = function (newClient, userName, password) {
  newClient.userName = userName;
  application.acceptConnection(newClient);
};

Along with the IP address (the ip property), each client has properties that contain the name of the user agent, referring page, and connection protocol. Other properties of the client object include readAccess and writeAccess, which can be used to control what relative URIs the client can access, and therefore what streams and shared objects are available to each client. In Example 4-2, the client is allowed to write to any resource in the public directory or its subdirectories because writeAccess is "/public". The client is allowed to read (access) any resource in any directory because readAccess has been set to "/", which is the root of any relative URI within the instance.

Properties can be added to the client object; in this example, a userName property is added dynamically. The userName variable passed into the onConnect( ) method is the name with which the user logged in; the code stores it as a propertyalso named userNameof the client object so that it is available even after the onConnect( ) handler exits.

The onConnect( ) handler in Example 4-2 allows the client to connect to the application instance by invoking application.acceptConnection( ). Client connection requests can also be rejected using application.rejectConnection( ). Calling these methods inside onConnect( ) is not really necessary. If onConnect( ) returns true, the client connection is accepted; the connection is rejected if onConnect( ) returns false. More importantly, if onConnect( ) returns nothing or null, the client is left in a pending state and is unable to communicate with the server. Connections for pending clients can still be accepted or rejected outside of the onConnect( ) method by calling application.acceptConnection( ) or application.rejectConnection( ).

If the application.onConnect( ) method is not defined, all client connections are accepted and all clients are given global read and write access equivalent to setting readAccess and writeAccess to "/".


4.4.4. application.onDisconnect( )

The application.onDisconnect( ) method is called when FlashCom detects that a client with an accepted or pending connection has disconnected from the instance. In the example, the client.userName property is used to identify who is leaving.

4.4.5. application.onAppStop( )

Finally, application.onAppStop( ) is called just before the instance is shut down. It is passed an information object that specifies the reason for the shutdown; it can prevent the instance from shutting down by returning false.

4.4.6. Using the App Inspector to Run Scripts

To try out a script like the one in Example 4-2, create a text file named main.asc (or download it from the book's web site) and save it into a subdirectory of your applications folder named helloWorld. Find the app_inspector.swf movie (located in FlashCom 1.5's flashcom_help/html/admin directory). This .swf is a testing tool known as the App Inspector.

Start the app_inspector.swf movie by opening it in the Flash Player, or load the app_inspector.html page into your browser and enter the location of the server in the Host field. If you are running FlashCom on your workstation, enter localhost in the Host field. If FlashCom is running on a remote server, enter the server's IP address or hostname. In the Name and Password fields, enter the administrator's username and password, which you chose during FlashCom's installation procedure.

After connecting, enter helloWorld in the App/Inst field and click the Load button, as shown in Figure 4-3. If the instance doesn't load, an information icon should appear near the Load button. Click on it to see what went wrong, fix and resave your script if necessary, and try again.

Figure 4-3. Loading an application in the App Inspector following login


If the helloWorld/_definst_ instance is not loaded successfully, click on the View Detail button, as shown in Figure 4-4.

Figure 4-4. The App Inspector after loading a helloWorld application


If the helloWorld/_definst_ instance is loaded successfully, click on the Live Log tab of the App Inspector. Click the Reload App button to force the instance to restart so that you can see the output from the test script's application.onAppStart( ) method.

Figure 4-5 shows the output in the Live Log area of the App Inspector after the helloWorld application was restarted.

Figure 4-5. The App Inspector after restarting helloWorld/_definst_


The log shows the application instance was shut down and restarted, but the messages do not appear in the order you might expect. System messages and trace( ) messages from the script are often intermixed. For example, the system message "Loading of app instance: helloWorld/_definst_ successful" appears in between messages generated by the trace( ) function while the instance was unloading in the onAppStop( ) method. The messages generated by the script in the previous output listing occur only in the onAppStart( ) and onAppStop( ) methods. To see messages related to clients connecting and disconnecting from the application instance requires a movie that connects to and disconnects from the instance. For this purpose, a test movie is supplied on the book's web site as part of the helloWorld.zip archive. Test movies are an important tool. A good but simple test movie should allow you to:

  • Enter or select different application instance names to which to connect

  • Enter a username and password or other connection parameters

  • Read all the status and error messages the client receives or generates

  • Easily extend it to add features as necessary

The output in Figure 4-6 shows the Live Log area when a connection is made and then dropped from a client. The IP address of 127.0.0.1 indicates that the client was running on the same system as the FlashCom Server.

Figure 4-6. The App Inspector after a client connects to and disconnects from helloWorld/_definst_


Twenty-three minutes after the client disconnected, the instance shuts down and produces the output shown in Figure 4-7 in the App Inspector.

Figure 4-7. The App Inspector after the helloWorld/_definst_ instance shuts down


The output in the Live Log area of the App Inspector shows data such as startup and shutdown times, the client IP address and username, and when the client connects and disconnects. The App Inspector and server-side trace( ) statements are essential for testing and debugging server-side scripts.