Close Flash connection on browser close?

Discussion in 'Web Design and Development' started by whooleytoo, Oct 1, 2009.

  1. whooleytoo macrumors 603

    whooleytoo

    Joined:
    Aug 2, 2002
    Location:
    Cork, Ireland.
    #1
    I have a live collaborative Flash site, where promptly detecting if users leave (close their browser window) is quite important.

    I've tried using the Javascript onbeforeunload() handler to send a message to the Flash movie telling it to disconnect, but there's a catch:

    It only works if I show an "Are you sure you want to close?" type alert. If the window closes straight away without an alert, that disconnect message is never sent by the Flash movie. I know delaying the window close is poor practice, but is there any way to do so, even for a fraction of a second, which would be enough for Flash to send an "I'm disconnecting" message?
     
  2. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #2
    You can take a look at the setTimeout function for JavaScript. It can likely meet your need for setting a little delay.
     
  3. whooleytoo thread starter macrumors 603

    whooleytoo

    Joined:
    Aug 2, 2002
    Location:
    Cork, Ireland.
    #3
    Thanks for the response! Unfortunately, I don't think that can do what I need. The only way I know of delaying the window close is by returning a value from onbeforeunload() (which will cause a Javascript alert to be displayed.) E.g.

    Code:
    window.onbeforeunload = function(evt)
    {
        setTimeout("okToClose()", 1000);
        return "Are you leaving me?";
    }
    
    function okToClose()
    {
        ...
    }
    
    So the problem is - the setTimeout() call won't prevent onbeforeunload() from returning, thus the window will close anyhow (if I return nothing) or show an alert (if I return a string).

    If there was any kind of blocking call which would prevent the function returning that would work; even though that would be an ugly hack.
     
  4. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #4
    Here's some quick JavaScript that I worked on and tested with Firefox. Stuff is where you'll do your Flash stuff. The commented out alert line was just a way to get some feedback, but isn't necessary. This way it'll only wait as long as it needs to finish the Stuff. Make sure to keep the done variable though, it's key here. I also used onunload rather than onbeforeunload as I'm not sure all browsers support it. Though, I didn't even need to use the Stall function to have it work. How are you doing the flash stuff, is it running synchronously or asynchronously (AJAX)?
    PHP:
    var done false;
    window.onunload = function() {
      
    setTimeout(function(){Stall();},1);
      
    Stuff();
    };
    function 
    Stall() {
      var 
    0;
      while (!
    done) { a++; }
      
    //alert('done');
    }
    function 
    Stuff() {
      var 
    00;
      while (
    b++ < 60000000) { c++; }
      
    done true;
    }
     
  5. whooleytoo thread starter macrumors 603

    whooleytoo

    Joined:
    Aug 2, 2002
    Location:
    Cork, Ireland.
    #5
    Ah, I misunderstood what you meant originally. The above code (a bit ugly, but if it works who cares!! :) ) works perfectly on Safari, but not on IE on Windows (I get the "A script is causing this page to..." error).

    If I reduce the timeout, it works perfectly on IE, but the message never gets sent in Safari.

    I had previously tried the following, which I thought would work, but doesn't work on any browser! (I've tried all kinds of values for the timeout below, but presumably the problem is the loop will prevent the timer ever firing - there is no background thread which will fire the timer and stop the loop).

    Code:
    window.onbeforeunload = function (evt)
    {
    	// 22-Sep-2009 MW
    	// Disconnect FMS connection before closing..
    	var flashMovie=getFlashMovieObject("myFlashMovie");
    	flashMovie.windowClose();		
    
    	setTimeout("allDone = true", 200);
    	var a = 0, b = 0, c = 0;
    	allDone = false;
    	while (!allDone)
    	{
    		a++;
    		b++;
    		c++;
    	}
    }
    
    I used onbeforeunload as I thought it might offer me a little more time to send my disconnect message. I tried onunload too, and no joy..

    I'm using Actionscript's ExternalInterface to make the calls from Javascript -> Actionscript, then using the NetConnection class to send the message to "disconnect me". AIUI, they're all synchronous; and yet without some delaying mechanism, no message is sent.

    In any case, thanks! I appreciate your help.
     
  6. whooleytoo thread starter macrumors 603

    whooleytoo

    Joined:
    Aug 2, 2002
    Location:
    Cork, Ireland.
    #6
    Ok.. found a possible solution; this should work better since the delay is based on time; rather than on a numeric counter (which will vary a lot depending on the speed of the machine, the Javascript engine, etc)

    Code:
    window.onbeforeunload = function (evt)
    {
    	// 22-Sep-2009 MW
    	// Disconnect FMS connection before closing..
    	var flashMovie=getFlashMovieObject("myFlashMovie");
    	flashMovie.windowClose();		
    
    	var now = new Date();
    	var nowMS = now.getTime();
    	delete now;
    	
    	var destMS = nowMS + 200;
    	
    	while (nowMS < destMS)
    	{
    		now = new Date();
    		nowMS = now.getTime();
    		
    		delete now;
    	}
    }
    
     
  7. whooleytoo thread starter macrumors 603

    whooleytoo

    Joined:
    Aug 2, 2002
    Location:
    Cork, Ireland.
    #7
    FYI - finally got this working well. It seems to work better if the loop is in the Actionscript function in Flash, rather than in the Javascript function that calls it.

    But the main problem was - when Flash is busy, things just stop working. Even outgoing messages over a NetConnection fail. The simple solution: it turns out if you're streaming a webcam and a lot of data on the same NetConnection it gets bogged down. Open up a second NetConnection and use it for sending any important messages - including this 'Disconnect me' - and it all works fine. :)
     

Share This Page