Section 5.1. A Simple PublisherSubscriber Example

5.1. A Simple Publisher/Subscriber Example

Example 5-1 is a somewhat oversimplified but complete example script that shows the essential steps in publishing one live stream and subscribing to a second live stream. The example shows how video, audio, and ActionScript data can be sent via a published stream and received by subscribing to another stream.

Example 5-1. A very basic two-way messaging client
 //   writeln(  )   replaces   trace(  )   and writes messages into the   trace_txt   field. function writeln (msg) {   trace_txt.text += msg + "\n";   trace_txt.scroll = trace_txt.maxscroll; } //   onStatus( )   sets up the streams and buttons when a connection is // established or lost. NetConnection.prototype.onStatus = function (info) {   writeln("Level: " + info.level + ", code: " + info.code);   if (info.code == "NetConnection.Connect.Success") {     out_ns = new NetStream(this);     out_ns.attachAudio(Microphone.get( ));     out_ns.attachVideo(Camera.get( ));     in_ns = new NetStream(this);     in_ns.showMessage = function (msg) {       writeln(msg);     };     //   remote_video   is the instance name of an embedded video object.     remote_video.attachVideo(in_ns);     in_ns.play("public/" + remoteUserName);     connect_pb.setLabel("Disconnect");     send_pb.setEnabled(true);   }   else if (!this.isConnected) {     if (out_ns) out_ns.close( );     if (in_ns) in_ns.close( );     connect_pb.setLabel("Connect");     send_pb.setEnabled(false);   } }; NetStream.prototype.onStatus = function (info) {   for (var p in info) {     writeln("info." + p + ": " + info[p]);   } }; //   doSend( )   is called when the   send_pb   is clicked. function doSend (msg) {   out_ns.send("showMessage", input_txt.text);   input_txt.text = ""; } /*   doConnect( )   is called when the   connect_pb   is clicked.  * It stores the text in the   userName_txt   and   remoteUserName_txt   * fields in global variables for later use if a connection is  * attempted. See the   onStatus( )   method.  */ function doConnect (pb) {   if (pb.getLabel( ) == "Connect") {     userName = userName_txt.text;     remoteUserName = remoteUserName_txt.text;     nc.connect("rtmp:/courseChat/algebra101", userName);   }   else {     nc.close( );   } } function doSendStream (pb) {   if (pb.getLabel( ) == "Send Stream" && nc.isConnected) {     pb.setLabel("Stop Stream");     out_ns.publish("public/" + userName);   }   else {     pb.setLabel("Send Stream");     out_ns.publish(false);   } } send_pb.setEnabled(false); nc = new NetConnection( ); 

To create a NetStream object within a network connection, the NetConnection object must already exist and a connection attempt to FlashCom must have already been made by calling the connect( ) method. In Example 5-1, a new NetConnection object is created and then the user must enter both his username and the name of the remote user he wants to talk to. Then he must click the Connect button. When the connection is established, the NetConnection . onStatus( ) handler is called and two NetStream objects are created and initialized to send or receive data. The NetStream object that is designed to receive data tries to subscribe to a stream immediately, but the outgoing stream does not attempt to send anything until the user clicks the Send Stream button.

5.1.1. Publishing a Live Stream

In order to publish a stream, a NetStream object has to be created. In Example 5-1, the out_ns object is created within a connection by passing it a NetConnection object. The keyword this , which represents the current NetConnection object, is passed in this example because the NetStream object is created within the NetConnection.onStatus( ) method:

 out_ns = new NetStream(this); 

This statement could also have been written using the nc variable defined in the last line of Example 5-1:

 out_ns = new NetStream(nc); 

Once the NetStream object out_ns exists, audio and video data sources can be attached to it:

 out_ns.attachAudio(Microphone.get(  )); out_ns.attachVideo(Camera.get(  )); 

The Microphone and Camera classes are available only within Flash movies (not on the server) and provide a number of static methods , such as get( ) . In the example, Microphone.get( ) returns the Microphone object last selected in the movie's Player Settings dialog box. Passing the Microphone object to the out_ns.attachAudio( ) method makes the sound data captured from the microphone available to the out_ns stream. The Camera.get( ) method returns a Camera object and works in the same way. Attaching the Camera object to the stream using the NetStream . attachVideo( ) method makes compressed video data from the camera available to the stream. Although it isn't a best practice to pass the return value from the get( ) methods directly to the attachAudio( ) and attachVideo( ) methods, we use this approach for demonstration purposes. Chapter 6 considers other alternatives.

The Camera and Microphone classes provide other methods for managing video and audio sources and events, and are described in detail in Chapter 6.

Before actually publishing the stream, it is a good idea to set up an onStatus( ) event handler that will receive notifications when stream events occur. In Example 5-1, a default onStatus( ) handler is attached to NetStream.prototype , making it available to all NetStream instances. Any NetStream object that is not assigned its own handler will use the one assigned to the prototype. Defining an onStatus( ) method on the NetStream.prototype is convenient for testing and exploration but is not normally used in production code. In Example 5-1, the onStatus( ) handler simply displays the information object's properties in the trace_txt field.

The outbound stream is published to the server using NetStream.publish( ) after the user clicks the Send Stream button:

 out_ns.publish("public/" + userName); 

The required parameter is the relative URI that identifies the stream. In this example, the stream name will depend on the username provided. If the username is "brian," the URI will be public/brian , which becomes the address of the published stream within the application instance to which the movie is connected. If another movie is already publishing a stream with the URI public/brian , the attempt to publish the stream will fail and a "NetStream.Publish.BadName" error message will be returned in the info.code property passed to onStatus( ) . The directory name public has no special meaning in this example and was used to emphasize that stream names are relative URIs.

The publish( ) method has a second, optional parameter (discussed later) that determines whether the stream is recorded. If the parameter is omitted, the stream is not recorded and is available as a live stream only.

Once the stream has been published, ActionScript data can also be sent on the stream at any time using the NetStream.send( ) method. In Example 5-1, NetStream.send( ) is used to create a simple text messaging feature. When one user enters some text in the input_txt field and clicks the Send button, the other user will see the text appear in her trace_txt field.

ActionScript data that is sent on a stream is always sent as part of a request to invoke a method. In Example 5-1, when one user enters text in the input_txt field and clicks the Send button, the doSend( ) function is executed, which in turn calls out_ns.send( ) to send the text data. The NetStream.send( ) method is always passed the name of a remote method to call as the first parameter, as follows :

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

In Example 5-1, the remote method showMessage( ) will be called on any NetStream objects subscribed to the stream and will receive the text the user typed into the input_txt field.

The showMessage( ) method should be defined on the subscribing NetStream , for example:

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

Even if the publishing stream defines a showMessage( ) method, it will not receive any remote method calls it sends on the stream. Only subscribed streams receive remote method calls.

In summary, the steps to publish a live stream are:

  1. Create a NetConnection object:

     nc = new NetConnection(  ); 

  2. Use NetConnection.connect( ) to attempt to connect to an application instance. The connect( ) method must be called before attempting to create a NetStream object:

     nc.connect("rtmp:/courseChat/algebra101", userName); 

  3. Create a new NetStream object on a NetConnection object by passing the latter as a parameter to the NetStream constructor:

     out_ns = new NetStream(nc); 

  4. Attach any audio or video sources to the stream using attachAudio( ) and attachVideo( ) methods of the NetStream class:

     out_ns.attachAudio(Microphone.get(  )); out_ns.attachVideo(Camera.get(  )); 

  5. Make sure the NetStream object has an onStatus( ) handler, either by defining one on NetStream.prototype or by creating a method for the individual NetStream object. This step is not required but is recommended.

  6. Publish the stream using NetStream.publish( ) :

 out_ns.publish("public/" + userName); 

5.1.2. Subscribing to a Live Stream

Subscribing to a stream is a little different than publishing one. To publish audio and video in a stream, we attached a Camera and a Microphone object to the stream. However, to play a stream and display it in the Flash client, we have to attach the stream to a Video object. We also have the option of attaching the stream to a movie clip to control the stream's audio. We always start by creating a NetStream object within a NetConnection and then attach objects that display video or control audio. Methods can also be added to the stream to receive remote method calls. Here, we create a new NetStream , attach it to a Video object, and play the stream. Text messages received by the stream will be displayed using the showMessage( ) method of the NetStream object:

 in_ns = new NetStream(nc); remote_video.attachVideo(in_ns); in_ns.showMessage = function (msg) {   writeln(msg); }; in_ns.play("public/" + remoteUserName); 

In Example 5-1, the in_ns stream is attached to an embedded Video object named remote_video . Embedded Video objects are similar to movie clips. They can be placed on the Stage to display video and have some of the same properties as movie clips. For example, you can manipulate the height and width of an embedded Video object by setting its _height and _width properties. To place a Video object on the Stage, use the Library panel's pop-up Options menu and choose New Video. Once an embedded Video object is available in the Library, it can be dragged to the Stage and resized, or it can be placed within a movie clip. Once on stage, a Video object must be given an instance name using the Properties panel in order to refer to it via ActionScript.

By default, audio arriving within a stream is automatically forwarded to a sound device on the local computer so that it can be heard . It is not necessary to attach a stream to anything in order to hear audio. However, to control audio volume, the stream can be attached to a movie clip and then a Sound object can be created on the movie clip to control the volume of the audio. For example, to set the volume to 50, an existing movie clip instance named stream_mc could be utilized this way:

 stream_mc.attachAudio(in_ns); soundControl = new Sound(stream_mc); soundControl.setVolume(50); 

Although the Sound object did not work properly in the Flash Player 6 initially distributed with the Flash MX development environment, later versions properly control stream volume. The Player used in the authoring environment is not automatically upgraded when the browser Player plugin is upgraded. To upgrade the Player used in the Flash development environment, visit:

http://www.macromedia.com/support/flash/downloads.html


In summary, NetStream objects have attachVideo( ) and attachAudio( ) methods that are used to attach video and audio sources when publishing a stream. Video objects have an attachVideo( ) method that is used to attach video arriving within a stream to an embedded Video object. Similarly, the MovieClip class has an attachAudio( ) method that attaches incoming audio to a clip.

If a publishing stream calls a remote method, that method must exist on the subscribing stream or nothing will happen. In Example 5-1, the NetStream.send( ) method is called and passed the remote method named showMessage( ) and a text string to pass into it. Defining a showMessage( ) method on the subscribing stream, as shown earlier, is all that is required to respond to the remote method call.

Once the in_ns stream is ready to receive audio, video, and remote method calls, you can subscribe it to a stream on the server using NetStream.play( ) :

 in_ns.play("public/" + remoteUserName); 

Following through on the stream names used in Figure 5-1, if the remoteUserName variable contains the string "robert", then the relative URI of the stream being requested via play( ) will be public/robert . If no stream of that name exists, no error will be returned. Instead, the application will simply return data from a stream of that name if and when one is published.

This short demonstration script can be used by two people to have a video, audio, and text conversation, but it does suffer from some serious limitations. For example, text messages appear only in the subscriber's text field and there is no way for either user to know the other is available and wants to chat. Also, the program should not rely on both users entering both usernames in order to chat. Some additional programming, most often using remote method calls and/or shared objects, is required to overcome these limitations. Keeping track of and managing streams using shared objects was first introduced in the helloVideo application in Chapter 1 and is described in detail in Chapter 8.



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