Brendan Tompkins

Sponsors

The Lounge

Wicked Cool Jobs

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
End User Sessions When the Browser Closes With Remote Scripting

I literally stumbled across this solution while creating the WSMQ Instant Messenger demo that I posed about last week.   My problem was that I needed a way to log users out of the chat application when they closed their browser window.  Since I was storing my list of users in the application, they'd hang around indefinitely unless I manually pulled them out, or until the worker process restarted.

Then it occurred to me that this may also work as a mechanism to automatically time out a users session when they close their browser.  On a big website, you could have hundreds of sessions sitting around taking up memory, that aren't being used.  Depending on what you've decided to load the session up with, this could be a resource hit for your web server.  By default, these sessions will timeout after 20 minutes, but with this method, you can time them out as soon as the user closes their browser. 

The solution requires using this Remote Scripting Java Script library from Alvaro Mendez that allows you to call any method on an ASP.NET page from within client-side Java Script.  It also requires that pages in your site inherit from a PageBase class (which is good practice and hopefully you're doing this anyway).

Step 1 - Add the RemoteScripting.cs file to your project

This just has to live somewhere in your project, or in a referenced DLL.  If you have a [Your Namespace].Web project, this would be a good place to put this so that you can re-use it across web applications.

Step 2 - Give RemoteScripting a chance to handle each request

You can do this in a variety of ways, but one sure way is to add the following line of code to your PageBase's OnInit method.  What this will do it let RemoteScripting handle the request if it needs to.  Now, there is a bit of a trade off here, you are adding extra cycles to each request, so you may want to consider the overall payoff here.  It's not much processing if there was no remote method called.

protected override void OnInit(EventArgs e){
  // If it was called invoke the remote method and get back to the client
  RemoteScripting.InvokeMethod(this);
}

Step 3 - Add an EndSession method to your PageBase Class

This will be the remote method that gets called when the browser window is closed.

public void EndSession() {
  // This will call the application session on end method.
 
this.Session.Abandon();
}

Step 4 - Include the rs.js Client Side JavaScript Library on your Pages.

You've got to add the rs.js script which comes with the RemoteScripting to each page.  You could do this in the ASPX code, or pro grammatically in your PageBase.  A good place to do this would be in your OnPreRender method.

Step 5 - Add a JavaScript event handler to your ASPX page's onbeforeunload event.

Unfortunately, the following script only works with IE.  If anyone can figure out how to get it to work with Firefox, that would be awesome.  It at least doesn't cause problems in FireFox, so it should be relatively harmless...

// Wire up the onbefore unload event
window.onbeforeunload = EndSession;

// Close all open chat windows, and call the remote method to logout of the application
function EndSession()
{
  
// Get the real ASPX page name
  
var sPath = window.location.pathname;
  
var sPage = sPath.substring(sPath.lastIndexOf('/') + 1);
   
if(sPage == '') sPage = "Default.aspx";

  
// They're in a  popup window, don't kill the session here!
   
if(window.opener != null) return;

 

   // Only want to run the endsession for IE, no way to tell currently if it's not IE and
  
// the window is closing
  
if(window.event != null) {
    
var abssize = document.body.offsetWidth-30;
    
if (window.event.clientY < 0 && event.clientX >= abssize)  {
           RS.Execute(sPage
, "EndSession");
     }
   }
}

That's it!  Now when someone closes their browser, the remote method should be called, and the session gets killed.  I'd recommend that if you try to do this, you do some debugging to make sure that you have everything wired up correctly, since there's no UI component to this.

Good Luck!

-Brendan


Posted Tue, Jan 25 2005 8:30 AM by Brendan Tompkins
Filed under:

[Advertisement]

Comments

Rob wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Thu, Sep 15 2005 12:53 PM
This code is better than not doing anything for a window close however, I can think of a number of situations where this wouldn't work. Perhaps it is fine to rely on the normal timeout for a session, if the user does any of these. Although, you would likely want to do something about the first one.

1. if the mouse happens to be near the window close button and the user presses F5 to refresh the page, you will log them out.

2. if the user uses File->close, you will NOT log them out

3. if the user uses Alt-F4 to close the browser, you will NOT log them out.
mdh wrote re: VB equivalent?
on Mon, Nov 7 2005 11:19 PM
Great Work, this is exactly what I have been looking for, only I need it it VB.net I have tried to covert but it doesnt seem to work,

could you point me in the right direction...anything I need to pay attention to?

Thanks

send_to_mdh@yahoo.com.au
Arun wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Tue, Apr 11 2006 10:23 AM
This looks great.  But I can't see this running as expected.  When I close the window, the RemoteScripting call is made from the javascript, but when the control reaches OnInit method on the server side, the execution ends.  This may be because of the closure of the window even before the control reached there.  Can someone help me fix this?

You can mail me at arunkumarkvs@gmail.com
AmalS wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Wed, Apr 26 2006 7:00 AM
Good.It is working fine for me.
Grammar Nots wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Fri, Sep 8 2006 8:49 AM

This just keeps bothering me: "Unfortunately, the following script works with IE."  Insert "only" in front of "works" and it suddenly makes much more sense, unless we're disappointed by IE actually functioning.

Carl Nelson wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Fri, Oct 6 2006 12:28 AM

This works great for the "x" button. I modified it to also check for Alt-F4. Unfortunately, I cannot figure out a way to trap File->Close, or right-clicking on the task bar and selecting Close.

To make this work, I added the following script code:

// Track key presses

document.onkeydown = checkKeyCode;

// global variables used by checkKeyCode and checkForBrowserClose functions

var oldKeyCode;

var closingKey;

// what key was pressed?

function checkKeyCode(key)

{

 var keyCode;

 if (window.event)

 {

   keyCode = window.event.keyCode;

 }

 else if (key)

 {

   keyCode = key.which;

 }

 // If the user pressed the Alt key(18) and then F4(115), they are trying to close the browser

 if((keyCode == 115) && (oldKeyCode == 18))

 {

   closingKey = true;

 }

 oldKeyCode = keyCode;

}

I changed this line in your function:

      if (window.event.clientY < 0 && event.clientX >= abssize)  

to this:

     if (((window.event.clientY < 0) && (event.clientX >= absSize)) || (closingKey))

and added this line at the end of your function, before the closing brace, to reset the closingKey flag:

    closingKey = false;

I hope this helps someone, and I hope someone can figure out the File->Close method.

Thanks,

Carl

Carl Nelson wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Fri, Oct 6 2006 12:31 AM

Sorry, I should have written:

if (((window.event.clientY < 0) && (event.clientX >= abssize)) || (closingKey))

(I had changed abssize to absSize).

Thanks,

Carl

Nick wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Wed, Nov 8 2006 9:12 AM

Nice code.  But I am having a problem in my app.  I create temporary directories during execution.  In the EndSession function mentioned above I call Directory.Delete(), right before Session.Abandon(),  to erase them.  However the Delete() works erradictly over a remote connection.  Sometimes it deletes the folders and more often it does not.  Could it have anything to do with garbage collection upon exiting the app?

Any ideas?

Nick

Nick wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Fri, Nov 10 2006 7:29 AM

Nevermind.  I figured it out.  The remote connection I was using was through a vm and for some reason the vm instance of my app does not end the session upon closing of the browser.  It ends after the default 20 mins.  Not sure why this happens with the vm, but whatever.  It works fine otherwise.

Nick

Harry wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Mon, Dec 11 2006 11:19 AM

Great article!  I got this to work on a standard aspx page on IE 7, but I cannot get it to work with a page nested in a master page in IE 6.  Is there any different I need to do?

Thanks in advance,

Harry

Carl Nelson wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Fri, Dec 15 2006 10:34 PM

Hi, Harry.

Works fine for me in IE6. I have the call in my master page, not in a page contained by the master page. Or do you mean a nested master page? I haven't tried it that way; I had too many problems with nested master pages.

BananaNguyen wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Thu, Jun 14 2007 11:43 PM

Good job, this is exactly what i need at current. Thanks.

Bhanu wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Tue, Jun 19 2007 7:33 AM

I have nested master pages and i wrote a web service to call a session.abandon and calling that method from master pages through script manager tag and enablepagemethods true and calling service method as PageMethods.AbandonSession(), The definition of this i gave in web service.

But the problem is Pagemethoda.abandonSession() is not calling my web service method even after giving a service refernce in my script manger tag

Subburaj.S wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Mon, Jul 9 2007 4:53 PM

Hi,

            I have done for all options to close the browser window like alt f4, file>>exit, browser close by calling body unload() but the Firefox raises this event even if call any event in the page like linkbutton onclick event. Awiting for this solution.

Thanks,

Subburaj.S

Carlos Solis wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Fri, Aug 10 2007 3:22 PM

I think its a great code, but a better way to do this is described in the link below

Add to the close window options when in IE7 the user close the tab window.

aspalliance.com/1294_CodeSnip_Handle_Browser_Close_Event_on_the_ServerSide

Nisar Khan wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Tue, Jan 29 2008 2:51 PM

is there a download project?

thanks.

mkuczara wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Tue, Jan 29 2008 3:11 PM

No let someone show me how to handle tab closing (FF and IE7) and i'll be happy.

leo wrote re: End User Sessions When the Browser Closes With Remote Scripting
on Mon, May 19 2008 5:12 AM

Working fine, but still there is a bug here..

After pressing Alt+F4, we will get an alert message.. Now click on cancel.. after that refresh the page..

Now alert is raising....

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Devlicio.us