FMS: Pending Clients Before Accepting a Connection

    January 31, 2007

I’m currently working on a video chat app using Flash Media Server and Flex. This will be version 2 of my excercise and this time I want to add real scalability to the app.

It already supports multiple rooms (which users can create) and is based around a concept of one master application instance holding a persistent SharedObject containing all the room information which each room fetches as it starts up.

A very popular UK dating/adult site (URL on request 😉 has bought the code from me and is running a modified version of Ameegos on their site and the chat is proving popular to put it mildly. So popular in fact that a single server couldn’t cope with the traffic and was frequently being brought to its knees by around 1500 concurrent video chatters.

And this is where the application failed: it wasn’t able to scale across multiple servers; instead users have to manually navigate between servers.

Some background info: the room objects hold a variety of information, amongst it is a roomid which is used to build the application/room instance on the fly. As the rooms were already connecting to the master instance serverside and proxying a SharedObject I figured it wouldn’t be too hard to store an entire RTMP string inside each room, effectively allowing unlimited servers to be added (in theory each room could have its own server although that’s never necessary in this case as each room is limited to 70 to 80 users).

Long story short I went ahead and started building the serverside application which, if you have ever had to debug multiple instances of multiple applications on FMS, is *not* a nice thing to do.

The one problem I had to overcome was this: whe the very first user connects to the application (Which at this stage is not yet running) is automatically kicks onAppStart into life. Inside the onAppStart handler I am setting up my serverside connection to fetch the SharedObject contents from my master instance (no user ever connects directly to the master). I then make decisions based on that data as to where to send the user (best server/room in terms of current traffic). This was tricky because the SharedObject onSync would not fire quick enough before the onConnect was invoked and the connection accepted – this meant that crucial room data wasn’t present in time and the first connection by the very first user was rejected. A rare case but still I wanted to fix it. But how?

I remembered reading about putting clients into a pending state before verifying credentials and accepting the connection later on. This should work for SharedObject related delays too…

A browse through the docs made it clear that this code would put a connecting client into pending (neither accepted nor rejected). Note: code formatting is a bit screwed up:

application.onConnect = function(client)
   return null; // client is now pending }

This was great but how can I accept this connection later on? How would I identify this particular pending client? Owen to the rescue who suggest to save a reference to it in the application scope:

application.onConnect = function(client)
// store client for approval this.client = client;
return null; // client is now pending }

This way I was able to process the connecting client and once the onSync returned approve it using a function that I could call from anywhere in my code, such as this:

approveConnection = function()
   if (application.client)
   // accept the connection application.acceptConnection(application.client);

What I still don’t understand if this is really the right way to do it. What would happen if multiple clients connect at the same time – how does this code approve the right client reference? If I had multiple clients in a pending state would this code still work? Right now (with a single client) it works fine but I have a feeling that I may need to match the correct client via a application.clients lookup somehow or risk accepting the wrong one… Can someone clarify?


Reddit | Furl

Bookmark WebProNews:

Stefan is a certified Flash Developer who has been involved with Flash Media
Server since its very early days. From his home office in the UK he has
handled a variety of projects, specializing in Flash Video and Rich Internet
Applications for clients that include CNET, USA Network and Unilever. Stefan
is the author of a series of Adobe Developer Center articles, has spoken at
several industry events and contributes a regular column on Flash Video to
Streaming Media Magazine. His site is one of the
largest online resources on Flash Video.