Accessibility

Flash Communication Server Article

 

Clustering Flash Communication Server for Live Webcasts

Jake Hilton

Lead Flash Developer
jakehilton.com
Huddle

Novell Inc. was looking for a web streaming solution that would deliver a high-quality video/audio-enabled presentation. On top of that, they wanted to customize the presentation of that video to illustrate the Novell brand. Novell also wanted a data-enabled solution that not only handled video playback, but also facilitated real-time interactions between client and presenter (Figure 1).

The Novell Critical Mass Training Project interface

Figure 1. The Novell Critical Mass Training Project interface

As the developer for Novell's solution, I looked in forums and on lists to try to see how others had approached this problem, but to no avail. Others were having the same problems that I was experiencing, and it took a few weeks of trial and error until I came up with the solution that I will share with you in this tutorial.

A solution like Novell's demands a stable, high-performance infrastructure. In this tutorial, I'll go over how to create an environment with multiple Flash Communication Server installations. I'll show you how to cluster them to disperse live events across multiple processors, increasing your possible bandwidth and heightening performance.

Requirements

To complete this tutorial you will need to install the following software and files:

Macromedia Flash Communication Server

Macromedia Flash MX 2004

Tutorials and sample files:

Note: The downloadable ZIP file contains two files for you to install:

Prerequisite knowledge

Intermediate Flash Communication Server knowledge as well as AS 2.0 experience

Understanding the Clustering Process

One of the first things you should consider when deploying a Flash Communication Server application is hosting. There are several methods for hosting Flash Communication Server. You could have a single dedicated Flash Communication Server. Or you could have many servers, which share machine time with other web or application servers. In this tutorial, I will discuss the multiserver environment. I won't go over the specifics of how to set up each individual server, but will touch only on what you need to understand the process of creating the multiserver environment. To learn how to set up Flash Communication Server, refer the documentation that comes with the installation files.

When I first started discussing clustering Flash Communication Servers, other developers and as seen on lists like the FlashComm Mailing List, Flashkit Communication Server MX forum, and Macromedia Flash Communication Server forums, I learned that there are different schools of thought about the best approach:

Which of these three is the best design? It depends on what type of application you are running. All of these designs will fulfill the need, which is to provide a stateless architecture that will allow for disconnections and quick reconnections of live streams, without incurring problems of syncing or losing your place in the stream. For clustering streaming events, I believe the third—having multiple master servers—is the best model. Let me explain my thinking.

Let's say for example you have an audio webcast that is expected to have a large attendance—about 1000 people. You may think to yourself, "One server could handle that load. Why do I need multiple servers?" This is a good question. And there's a one-word answer: redundancy.

Imagine that in the middle of the webcast your one server decides to take a break. What happens to your webcast? Well, it's not going to be pretty. You could end up playing banjo for coins on the street corner.

I would rather take the safe approach. Have multiple master servers, so that if one fails, then the other servers can handle things and not lose your stream. Even if you can't handle the whole webcast, at least you can offer the playback.

My team has put our servers behind a switch that does load balancing, so if one of the servers goes down, the switch balances traffic between the live servers automatically.

Ironically, we don't have our two Flash Communication servers on super high-end boxes. But because of the combined power of the OSs running on them and the Flash Communication Server software, they do surprisingly well under load. We balance between two HP Proliant DL360 G2 Dual 1.4 GB processor machines with 4 GB of RAM running SUSE LINUX Enterprise Server.

The switch we use is a Foundry ServerIron Layer 4 switch. It balances based on a least connection configuration. The switch does periodic health checks using UDP pings on the ports that the Flash Communication Server uses. If a server goes down, then the switch immediately directs all requests to the live server until the downed server comes back online. The switch is not specific to streaming protocols but works great under this design.

We have reliably served up over 900 audio streams concurrently without problems.

Programming for Dual-Server Connections

So how can you do this? I'll lay it all out. The nice little MultiConnection.as file included in this tutorial is something I wrote to overcome this clustering problem. It is not all-inclusive, nor the end-all solution. It is a base to work from to eventually build a well-oiled program specific to your organization.

The MultiConnection.as file is a stripped-down version of the NetConnection object coupled with the NetStream object and the remote SharedObject object. So it attempts to combine and accomplish what those three objects do individually. There are a few drawbacks as far as status message interaction and the like that you can work around, but for the most part it works great. Now I'll dive into the actual code that makes it work.

Working with the New Class

Place the MultiConnection.as file in your class library that you have associated with your Flash authoring environment. If you haven't set one up, then simply copy the MultiConnection.as file to your computer and in the Flash authoring environment, click the Menu button in the Actions panel (it is located on the top right of the panel) and select Preferences. From there select ActionScript 2.0 Settings, and then create a new class path to the folder where you saved the MultiConnection.as file.

Once you have placed the MultiConnection.as file in your class library, open it and change the path declaration (com.novell.MultiConnection) in the class to match your path (your folder where you have the class saved). The default path will be com.novell and you should change it to whatever your path is. I'd recommend using the de facto declaration style com.domainname, but that's just me. If you use the editor in Flash MX 2004, then you can do a syntax check to make sure it validates. You should see no errors. Using this new class will resemble what you are used to with the NetConnection and NetStream objects. So let's start programming.

  1. Initially you need to either:

    • Put the main.asc file in an application directory on your servers, which will include your necessary server calls
    • Simply incorporate the server calls into the main.asc file you have for your specific application
  2. After uploading the new main.asc file incorporating the code, restart the application so that it uses this new main.asc file.
  3. Next, open a new Flash document and declare a new MultiConnection object as follows:
    import com.sitename.MultiConnection
    mc = new  MultiConnection();
    
  4. Then pass in an array of servers and applications you want to connect to.
    var server_array=new Array();
    server_array[0]="rtmp://67.50.48.147/test";
    server_array[1]="rtmp://server2.com/test";
    mc.connect(server_array);
    

    You can also put your array in short hand like so:
    mc.connect(['rtmp://server1.com/test','rtmp://server2.com/test']);
  5. At this point the script connects to the servers you specified and passes back status messages related to the connections. To see these status messages, you need to set up a status function to display the message:
    mc.onStatus = function(objIn){
    	trace(objIn.code);
    }

    If you set up a status function to trace out the output, you'll get the following message when you connect successfully:

    NetConnection.Setup.Success.

    Otherwise you'll see this message:

    NetConnection.Setup.Failed. 

    This means one of the servers hasn't responded in the specified 3-second timeout.

  6. After you have established and verified successful connections, you can set up NetConnections and shared objects.

    mc.onStatus = function(objIn){
    	if(objIn.code == "NetConnection.Setup.Success"){
    		trace(objIn.code);
    		mc.sharedObjectSetup ("sharedobject_so");
    		mc.setNetStreams();
    	}
    }
  7. Now set up a simple audio stream to go to the servers. Just add this code inside the success script.

    myMic = Microphone.get();
    mc.attachAudio(myMic);
    mc.nsStatus=function(objIn){
    	trace(objIn.code);
    }
    mc.publish ("webCastName","live");
  8. The following operators can also be used in conjunction with NetConnections—the function below is similar to the netConnection.call function:

    mc.callRemote("funcIn",callBackFunction,"serverToCall"[,arguments]);
    mc.ncClose();
  9. The following operators can also be used in conjunction with NetStreams:

    mc.attachVideo(myVid);
    mc.nsSend("servercall",[arguments]);
    mc.nsTime();
    mc.nsClose();
  10. To access shared object operators, simply call them by passing in the correct parameters and define sync functions. These include:

    mc.setSoValue ();
    mc.getSoValue ();
    mc.sharedobject_so_sync();
    

    An example might be:

    mc.setSoValue("sharedobject_so.data.userName”,”Foo”);

    And to retrieve the value:

    mc.getSoValue("sharedobject_so.data.userName”);

So the full client code you've written is:


import com.novell.MultiConnection
mc = new  MultiConnection();
mc.connect(['rtmp://server1.com/test','rtmp://server2.com/test']);
mc.onStatus = function(objIn){
	trace(objIn.code);
	if(objIn.code == "NetConnection.Setup.Success"){
		mc.sharedObjectSetup ("info_so",true);
		mc.setNetStreams();
		myMic = Microphone.get();
		mc.attachAudio(myMic);
		mc.nsStatus=function(objIn){
			trace(objIn.code);
		}
		mc.publish ("webCastName","live");
	}
}
mc.info_so_sync = function(){
	trace("so synced");
}

This code will connect to the servers and create a shared object named info_so on both servers, which will sync to the info_so_sync function. It also attaches a microphone to your NetStream object and starts streaming to your servers.

Where To Go from Here

So basically, you have taken the NetConnection, NetStream, and SharedObject objects and combined them to operate with multiple servers. Like I said earlier, this tutorial is not all-inclusive but merely a start on clustering multiple server applications. It should get you started, however, as you begin deploying large-scale, video-intensive applications.

About the author

Jake Hilton is a Certified Flash MX 2004 Developer who has worked with Flash Media Server since its infancy. He graduated from UVSC in Multimedia Communication Technologies—which may give some insight into his fascination with media on the web. He is currently the CTO of Huddle, a web communication and training tool.