views:

392

answers:

3

In my application the browser window connect with long polling(comet) with the server. If the user open several browser tabs, only one of them(called the master) communicate with the server and serves as a proxy for the other tabs. I want to use flash localConnection to exchange data between the tabs.

What happens when a user closes the master tab that holds the comet session? I can use javascript with the unload event to inform the other tabs that the master tab is closing and then close the localConnection but the unload event is unreliable. I can use polling to monitor the master tab connection object but it sound dirty.

When the master is closed one of the other tabs need to become the master. How do I make sure only one of them tries to become the master?

If a user close the tab without flash being able to close the localConnection, will it cause a memory leak?

Thanks

A: 

This is a very interesting problem. I'm half tempted to code something up to see how it would work! (If only I had the time!)

First, as for localConnection causing a leak, I think you will really have to test that, but I think it's possible but I've done a fair bit with LocalConnection in similar situations and have never seen a signficant memory leak (which is also to say, figuring what is a memory leak and what is just the GC being slow is always difficult to figure in non-trivial code in Flash)

As for the larger question on how to build this thing, I can't give a definitive answer, but here are a few ideas.

It seems to me the flow of logic for each SWF has to go something like this:

  • Check to see if I'm the first one (connect to the control channel)
  • If so, start control channel and tell JS to start comet connection via ExternalInterface
  • If not, connect to control channel and request two-way connection (at this point each slave SWF would generate a random ID and send that to the master - this ID would be used as the LC name for the data coming from the master to slave)

For handling the self-healing aspect I figure you could do something akin to a chain letter. That is, as each SWF connects to the master it could receive a list of the slaves. If the connection ever died each client would look to see where it was on the list. If it was the first slave on the list it would take over as the master - restart the control channel, and tell JS to start up a new comet connection. Then, each other slave would see that the server was back and would dequeue the now-master from their chain.

To handle holes in the chain from various clients dropping off, the master would coordinate that. Since it would be sending data to the slaves it would see immediately if a client dropped off. If a client did drop off it would simply tell the rest of the clients to remove that client from their chain.

Hope this helps!

Branden Hall
A: 

I also thought of a similar strategy.

The first window will become the master. Additional windows will become slaves and tell the master of their existance. Each slave will poll the master every 100ms to verify that it is alive. If the master is not alive, the slave that is next in the list become the master. Slaves that are next in the list stay slaves but expect the first slave to be the master. So in the next 100ms the rest of the slaves will try to poll the next master and if he is not there the next one will become the master...

It feels so dirty that I think I'll have to take a shower now. Going to do some coding.

Thanks

Well, if you're doing comet already to stream data, why do you need to do a heartbeat signal? If a client doesn't get the data it's expecting when it expects it you know "the king is dead" and start going down the list of successors.Really, Comet is already more than a little dirty. This is actually a fairly clean solution for dealing with the problem at hand - and it would probably end up working in a similar way if you were doing an actual socket connection.
Branden Hall
+1  A: 

Seeing as LocalConnection uses identifier strings to handle discovery, the following solution should work:

When the master tab closes, it informs one of the slaves that it is doing so. Then it closes its LocalConnection. The slave can now register a new LocalConnection with the same name as the one the master was using. The upshot of this is that the next time any of the other slaves try to contact the old master (using the old string) they will automatically find themselves talking to the 'new' master.

A similar effect could be achieved without resorting to the unload event (if that is undesirable). When the user closes the master tab, any app trying to connect to the LocalConnection it was using will get an exception. Instead of throwing an error, the slave app could instead infer that this exception means that the master has closed. It would then take on the master role and register a new LocalConnection with the same name as the master. The rest follows as above.

David Underwood