Helpful Information
 
 
Category: ASP
Global.asa / Session_OnEnd

I am tracking all activity on one of my sites, but if the user does not hit the LOGOUT button, I don't get a Logged out entry. I would like to stick it into the global.asa file so that it will do it when their session ends no matter how they exit.

This code below is what I have in my asa file now, but does not seem to be working.


Sub Session_OnEnd
IF Session("USER_ID") <> 0 THEN
oDb = Server.CreateObject("adodb.connection")
ConnStr = "SQL CONNECTION STRING"
oDb.Open(ConnStr)
oDb.Execute("INSERT INTO Log (mLogin, IP, EventTime, EventDescr) VALUES("+Session("USER_ID")+", '"+Session("USER_IP")+"', GetDate(),'Log Out')")
END IF

End Sub


Any ideas?

That is a good question, but I don't know if there's an easy (or possible) way to track this, since someone can simply close their browser window...

I'll need to think about that one for awhile. Anyone else have an idea?

:)

Originally posted by Eskimo
I am tracking all activity on one of my sites, but if the user does not hit the LOGOUT button, I don't get a Logged out entry. I would like to stick it into the global.asa file so that it will do it when their session ends no matter how they exit.

This code below is what I have in my asa file now, but does not seem to be working.


Sub Session_OnEnd
IF Session("USER_ID") <> 0 THEN
oDb = Server.CreateObject("adodb.connection")
ConnStr = "SQL CONNECTION STRING"
oDb.Open(ConnStr)
oDb.Execute("INSERT INTO Log VALUES("+Session("USER_ID")+", '"+Session("USER_IP")+"', GetDate(),'Log Out')")
END IF

End Sub


Any ideas?

Try that.

D'oh - a great solution. Why didn't I think of using a Session Variable? :)

Originally posted by whammy
D'oh - a great solution. Why didn't I think of using a Session Variable? :)

Yeah... I share your confusion Dave. Did George know what he was doing when he gave whammy a mod gun?;)

I'm the confused one. I gotta pay more attention. *sigh* :-/

Originally posted by whammy
D'oh - a great solution. Why didn't I think of using a Session Variable? :)

Do you mean you didn't think of just putting the code in the session_OnEnd in the global.asa(x)?

If the user clicks the X button of the browser or hits Alt+F4, Session_OnEnd is not executed. I also experienced that before. One alternative is this: (unfortunately, for IE only)

Call this on window onunload event on every page:

function onUnloadPage()
{
if (document.all){
if ((window.event.clientX < 0) && (window.event.clientY < 0)) //X button is clicked
{
//call your logout page
window.open('logout.asp', '', "features");

//or silent logout
//logout = new Image();
//logout.src="logout.asp";
}
}
}



Originally posted by Dave Clark


My question is... Have you established a default timeout value for the Session? If you have, then it shouldn't matter whether the visitor logs out or merely closes their browser without logging out. The Session timeout should still cause the Session End event to fire.

Sorry guys, I have been out of town for the last few days.

Even if somone is to close a browser, their Session still times out (default=20min), and should run the Session_OnEnd script. I have this (IF Session("USER_ID") <> 0 THEN) to gard aginst it running if they actually press the LOGOUT button, which few ever really do anyway.

I may have to go with the onUnLoad event for IE. This is used on an Intranet where IE6+ is required.

However, that won't allow me to find an answer to my question, only duct tape for this problem. I really would like to find a way to accomplish this, if I find out what it is, I will post it back here.

I've had a problem doing the exact same thing as you're trying to accomplish.

I haven't completely found a way around this yet, but I was thinking of using Application variables instead of session variables.

You need to make sure that your directory is set up as an application in IIS

I haven't really tried this yet to see if it'll work.. but the application varible syntax is the same as session..

so in global.asa
--------------------------
Sub Application_OnEnd
your code here
End Sub
--------------------------

I'll let you know if I get anywhere

~Quack

Application variables don't run when a user closes his browser. They run only when you Restart IIS, or when you edit the Global.asa file.

I don't think that will enable me to do what I need. But you have given me an idea.

The Sesson_OnStart scripts are working, but the Session_onEnd scripts are not.

Do I need to have : Application_onStart and Application_onEnd listed even though I'm not using them?

I guess it wouldn't hurt to have those in there - but I really don't think that's gunna change the problem.

To use something like an onUnload function would be really tricky - but could work - you could put it in an invisible frame that would fire the 'logout' page when the user exits the browser.

Also, when the user clicks the logout button, you could redirect the invisible frame to another page location (which would fire the onUnload function of the top frame, sending it to the logout page.)

I would say to have the unload function fire the page that calls the Session.Abandon function (which would then cause Session_OnEnd to execute) into a new window (set the width and height to 0 and have it close the window when it's finished)

Let me know if this helps

~Quack

I have chosen not to use the unLoad event.

Only for the reason of knowledge. I can't stand the fact that I don't know whats wrong with this. But I will find out, and this will work like its supposed to.

I agee with you, I don't think putting the appOnEnd or appOnStart will help anthing, must have been to early in them morning for my mind to function correctly. (Need more coffee...uhh).

I know it has to be some little detail that I have overlooked. This is my goal today, to fix this..

Let me know what you come accross, I've been trying to do a similar thing...

I have a site with many users - want to try and see if I can get a list of people who are logged in - but sometimes Session_OnEnd does not fire... so it still says the users is logged in (even after Sesison time out)

Is this kinda like what you're trying?

As far as my thing with the Application stuff - I was thinking of using a combination of application variables and session variables.

~Quack

You may be right, it may have to be a combination of the two..mmmm.

I bet your right, in order to have the Session_OnEnd to even be detected, you may need to have an Application_ running. I'll try that right now and see what I can get working.

I'm not trying to get a list of USERS ONLINE, I'm trying to track activity on a site that I designed. Any inserts/updates/deletes to the Database, what Table and Row was effected, who did it, when they did it, IP....blah blah blah. But with what I have right now, I can't tell when they logged off, unless they actuall press the LOGOUT button. Which few do.

gotcha, good luck Eskimo,


Please post your findings for us to see - I may be able to help you out a little more (I'm kinda busy right now ;))

Thanks

~Quack

I don't feel as confused as I once did. Hehe... I wish I could help you with this, but I'll stick with what I said in my first post, and ask around at work to see if anyone has a solution to this. :D

Eskimo, did you try my suggestion?



I have chosen not to use the unLoad event.

Only for the reason of knowledge. I can't stand the fact that I don't know whats wrong with this. But I will find out, and this will work like its supposed to.

I haven't yet, honestly, I must have missed your post...

I don't know how I did.. I'll give it a shot tomorrow and get back to ya..


Happy 4th of July guys.

hmmm I also facing same problem as I want to note time when user log offs.....

Problem with Glenn code is , as it should be on every page and the problem is user usaully have more than one window of IE of same instance

So lets say if user close one window then this code will be executed and in my case it will note the time of that user assuming that its loggin off but actually its not caz he just closed an extra window :confused:

Using the onunload event on the client (browser) side may catch some users but it's not a complete solution. It relies on the browser to make another HTTP request to your web site. That won't happen if a user's connection drops or their machine crashes or their proxy server dies.

The Session_OnEnd routine should fire whenever the user hits an ASP page that calls Session.Abandon or if the session times out.

You don't necessarily need to define an application in IIS for your pages. Your web site root is defined as an application by default.

You should check the code in your Session_OnEnd routine to be sure it's not dying because of some error. Try copying the code within it to a regular ASP script page and load it in your browser. It might just be a simple script error that's causing the problem.

Will do BrainJar, I do that later this afternoon, and try to get something posted by 4:30pm Central.

...But Session_OnEnd is not fired when the user closes the browser. Test that for yourself.


Originally posted by BrainJar

The Session_OnEnd routine should fire whenever the user hits an ASP page that calls Session.Abandon or if the session times out.


That's what Eskimo's problem is. He said that if the user clicks Logout link which calls session.abandon, session_onend is fired and executed properly (updates db), but when the user closes the browser without clicking the logout link, the db is not updated.

do asp.net then. :D

it's got both Page_Load and Page_Unload events. ;)

You don't necessarily need to define an application in IIS for your pages. Your web site root is defined as an application by default.

Partly true, but if i want to configure an app within the main app, like having its own scope, using its own app vars, app events and error handling routines, its own cache, and even its own global.asa, etc., then i would need to define that as another app root. ;)

MSDN

Platform SDK: Internet Information Services 5.1

Session_OnEnd
The Session_OnEnd event occurs when a session is abandoned or times out. Of the server built-in objects, only the Application, Server, and Session objects are available.



Why would the Session_OnEnd not fire after the default timeout (20min) has expired? No matter how they leave the site, would it not eventually time out?

Didn't you say this was for an Intranet?

If so, then to solve your multi-window problem, couldn't you use the users IP adress as a universal indicator of sorts. Like when they log in, it records their IP. Then if they open any duplicate windows, it looks for that IP in the logged in list and if it is, then it sets a variable that will make the session_OnEnd not run its code for that session. Since every browser window is its own session, this in theory could solve your problem.

Of course if they were accessing through a router running NAT the thing wouldn't work since those users would all have the same IP.

Since every browser window is its own session, ... Not quite. ASP assigns one session id for each client machine, meaning no matter how many browser windows are simultaneously open on the client, ASP uses the same session id to track the particular session.

Source:ASP docs, IIS:
After storing the SessionID cookie in the user's browser, ASP reuses the same cookie to track the session, even if the user requests another .asp file, or requests an .asp file running in other application. Likewise, if the user deliberately abandons or lets the session timeout, and then proceeds to request another .asp file, ASP begins a new session using the same cookie. The only time a user receives a new SessionID cookie is when the server administrator restarts the server, thus clearing the SessionID settings stored in memory, or the user restarts the Web browser. :D

Originally posted by Eskimo
MSDN


Why would the Session_OnEnd not fire after the default timeout (20min) has expired? No matter how they leave the site, would it not eventually time out?


but you want to record what time the user logout, don't you? If the user closes the browser without logging out, then the Session_OnEnd would fire only after the timeout expires, only this time the logout time of the user would be updated, which wouldn't be acccurate.

Originally posted by ReyN
Not quite. ASP assigns one session id for each client machine, meaning no matter how many browser windows are simultaneously open on the client, ASP uses the same session id to track the particular session.

Source:ASP docs, IIS: :D

Yes but still the Session_OnStart fires when you open two browsers windows to the same page. And the Session_OnEnd fires when either one of those windows timesout or is terminated.

If I log onto my site with IE6+ and press ctrl+n to open an identical browser, navigate through different areas with both browsers, and then press LOGOUT on only one browser, it logs off the other one also because the SESSON has been abandoned.

I do not use any special code to make this happen.










privacy (GDPR)