4

I'm to create a website for which I need to count the online users and show it on the home page all the time. I'm not interested to apply ready-to-use modules for it. Here is what I have already done:

Adding a Global.asax file to my project

Writing the following code snippet in the Global.asax file:

void Application_Start(object sender, EventArgs e) 
{
    Application["OnlineUsers"] = 0;
}

void Session_Start(object sender, EventArgs e) 
{
    Application.Lock();
    Application["OnlineUsers"] = (int)Application["OnlineUsers"] + 1;
    Application.UnLock();
}

void Session_End(object sender, EventArgs e) 
{
    Application.Lock();
    Application["OnlineUsers"] = (int)Application["OnlineUsers"] - 1;
    Application.UnLock();
}

Actually it works fine but I have found the following bug: --> Even if the user close the browser, the real count of online users is not shown since the session timeout is still alive!

Is there any solution but changing the session timeout interval?

mattmanser
  • 5,719
  • 3
  • 38
  • 50
Ali
  • 847
  • 2
  • 13
  • 37
  • Not really, you should implement some notification logic from the client side to inform the server that the user is about to navigate away but it may be a little tricky (that's why I never saw a web-site to do it...) – Adriano Repetti May 07 '12 at 11:38
  • You can call this function before working on `Application` `Session.RemoveAll(); Session.Clear(); Session.Abandon();` any function will work. Not tried but it should work. – Murtaza May 07 '12 at 11:45
  • if a user closes the browser you might not get a report of that on the server unless explicitly being reported from the client side. For this very case we have a session timeout which is an implicit report of end of the session. Hence to have an updated count you have to get triggered from the client side and for that you have to use any script – Syed Mohd Mohsin Akhtar Apr 23 '13 at 11:26
  • `The Session_Start/Session_End way has the problem that Session_End is only called for "InProc" sessions, not if the sessions are stored in StateServer or SqlServer.` – PreguntonCojoneroCabrón Nov 05 '16 at 22:13

4 Answers4

3

The Session_End event fires when the server-side session times out, which is (default) 20 minutes after the last request has been served. The server does NOT know when the user "navigates away" or "closes the browser", so can't act on that.

Hans Kesting
  • 38,117
  • 9
  • 79
  • 111
  • `The Session_Start/Session_End way has the problem that Session_End is only called for "InProc" sessions, not if the sessions are stored in StateServer or SqlServer.` – PreguntonCojoneroCabrón Nov 05 '16 at 22:14
3

You could use onUserExit jQuery plugin to call some server side code and abandon the session. Activate onUserExit on document ready :

<script type="text/javascript">
  jQuery(document).ready(function () {

    jQuery().onUserExit({
      execute: function () {
        jQuery.ajax({
          url: '/EndSession.ashx', async: false
        });
      },
      internalURLs: 'www.yourdomain.com|yourdomain.com'
    });
  });
</script>

And in EndSession.ashx abandon the session and server side Session_End will be called :

public void ProcessRequest(HttpContext context)
{
  context.Session.Abandon();
  context.Response.ContentType = "text/plain";
  context.Response.Write("My session abandoned !");
}

note that this will not cover all cases (for example if user kills browser trough task manager).

Antonio Bakula
  • 20,445
  • 6
  • 75
  • 102
0

No, It will take time to update until session is timedout...

Ovais Khatri
  • 3,201
  • 16
  • 14
0

It's the limitation of this approach that server will think user is logged in unless the session ends actually; which will happen only when the number of minutes has passed as specified in the session timeout configuration.

Check this post: http://forums.asp.net/t/1283350.aspx

Found this Online-active-users-counter-in-ASP-NET

Rahul
  • 76,197
  • 13
  • 71
  • 125