Jun 30, 2010

How to show number of online users / visitors for ASP.NET website?

here is the simplest approach that delivers acceptable accuracy when configured optimally:

Step 1:

    - first we need to add these lines to our global.asax file
      (if your website do not have it, create it by right-clicking on website in solution explorer,
       and choosing Add New Item > Global Application Class option)


    void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup
        Application["OnlineUsers"] = 0;
    }
 
    void Session_Start(object sender, EventArgs e)
    {
        // Code that runs when a new session is started
        Application.Lock();
        Application["OnlineUsers"] = (int)Application["OnlineUsers"] + 1;
        Application.UnLock();
    }
 
    void Session_End(object sender, EventArgs e)
    {
        // Code that runs when a session ends. 
        // Note: The Session_End event is raised only when the sessionstate mode
        // is set to InProc in the Web.config file. If session mode is set to StateServer 
        // or SQLServer, the event is not raised.
        Application.Lock();
        Application["OnlineUsers"] = (int)Application["OnlineUsers"] - 1;
        Application.UnLock();
    }

This will allow us that whenever some distant web visitor opens our website in his browser,
and new session is created for him, our  "OnlineUsers" variable in the global HttpApplicationState class instance
is increased.

Also when user closes his browser or does not click on any links in our website, session expires,
and our "OnlineUsers" global variable is decreased.

NOTE: we are using Application.Lock and Application.Unlock methods to prevent multiple threads
from changing this variable at the same time.

By calling Application.Lock we are receiving exclusive right to change the values in Application state.
But we must not forget to call Application.Unlock() afterwards.

Step 2:
    In order for this to work correctly we need to enable sessionstate and configure its mode to InProc value (in our web.config file):


        <system.web>
        <sessionState mode="InProc" cookieless="false" timeout="20" />
        </system.web>

In-process mode stores session state values and variables in memory on the local Web server.
It is the only mode that supports the Session_OnEnd event that we used previously.

Timeout value (in minutes, not in seconds) configures how long our sessions are kept 'alive' - in other words
here we set how long our users can be inactive before considered Offline.

In this example timeout is set to 20 minutes, so while our visitors click on some links in our website at least once
in a 20 minutes, they are considered online.
If they do not open any pages on our website longer than 20 minutes, they are considered Offline, and their session
is destroyed, so our online visitor counter is decreased by 1.
(You can experiment with lower or higher values of Timeout settings to see what is the best for your website).

Ok, so now we are done with configuration steps, let us see how to use this:

To show number of online visitors/users on your ASPX page you can use this code:
        Visitors online: <%= Application["OnlineUsers"].ToString() %>
Next you could put this code snippet in you UserControl, or inside Asp.Net AJAX UpdatePanel control, and
use Timer to refresh it in regular intervals without refreshing the whole page, but that is another story

example

macaddrees.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="macaddrees.aspx.cs" Inherits="macaddrees" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
   
    </div>
    </form>
</body>
</html>


macaddrees.aspx.cs


using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Management;
using System.Text;
using System.Net;



public partial class macaddrees : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {


        HttpBrowserCapabilities bc = Request.Browser;

        Response.Write("Name: = " + bc.Browser + "<br>");
        Response.Write("Version: = " + bc.Version + "<br>");
        Response.Write("BetaVesion: = " + bc.Beta + "<br>");


        string s = FindMACAddress();
        string strHostName = System.Net.Dns.GetHostName();
        string clientIPAddress = System.Net.Dns.GetHostAddresses(strHostName).GetValue(0).ToString();
        Response.Write("Ip:" + clientIPAddress + "<br/>");
        Response.Write("MacAddress:" + s.ToString() + "<br/>");
        //Response.Write("<br/>"+Request.UserHostAddress.ToString());
        // Response.Write("<br/>"+Request.UserHostName.ToString()+"<br/>" );
        Response.Write("Browser:" + Request.Browser.Browser.ToString() + "<br/>");


        Response.Write("Language:" + Request.ServerVariables["http_accept_language"].ToString() + "<br/>");

        Response.Write("OS:" + Request.Browser.Platform.ToString() + "<br/>");
        Response.Write("Date" + System.DateTime.Now + "<br/>");
        // string prevurl = Request.UrlReferrer.AbsoluteUri;


        Response.Write("Url:" + Request.Url.AbsolutePath.ToString() + "<br/>");
        Response.Write("online:" +  Application["OnlineUsers"].ToString()+ "<br/>");
     
       
      
    }


    public string FindMACAddress()
    {
        //create out management class object using the
        //Win32_NetworkAdapterConfiguration class to get the attributes
        //af the network adapter

        ManagementClass mgmt = new ManagementClass("Win32_NetworkAdapterConfiguration");
        //create our ManagementObjectCollection to get the attributes with
        ManagementObjectCollection objCol = mgmt.GetInstances();
        string address = String.Empty;
        //loop through all the objects we find
        foreach (ManagementObject obj in objCol)
        {
            if (address == String.Empty)  // only return MAC Address from first card
            {
                //grab the value from the first network adapter we find
                //you can change the string to an array and get all
                //network adapters found as well
                if ((bool)obj["IPEnabled"] == true) address = obj["MacAddress"].ToString();
            }
            //dispose of our object
            obj.Dispose();
        }
        //replace the ":" with an empty space, this could also
        //be removed if you wish
        address = address.Replace(":", "");
        //return the mac address
        return address;
    }
}



Global.asax

<%@ Application Language="C#" %>

<script runat="server">

    void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup

        Application["OnlineUsers"] = 0;
    }
   
    void Application_End(object sender, EventArgs e)
    {
      
    }
       
    void Application_Error(object sender, EventArgs e)
    {
        // Code that runs when an unhandled error occurs

    }

    void Session_Start(object sender, EventArgs e)
    {
        // Code that runs when a new session is started

        Application.Lock();

        Application["OnlineUsers"] = (int)Application["OnlineUsers"] + 1;

        Application.UnLock();

    }

    void Session_End(object sender, EventArgs e)
    {
        // Code that runs when a session ends.

        // Note: The Session_End event is raised only when the sessionstate mode

        // is set to InProc in the Web.config file. If session mode is set to StateServer

        // or SQLServer, the event is not raised.

        Application.Lock();

        Application["OnlineUsers"] = (int)Application["OnlineUsers"] - 1;

        Application.UnLock();

    }
      
</script>

output


Name: = Firefox
Version: = 3.6.3
BetaVesion: = False
Ip:192.168.11.2
MacAddress:0017C4960693
Browser:Firefox
Language:en-us,en;q=0.5
OS:WinXP
Date3/13/2010 6:21:42 PM
Url:/validateuser/macaddrees.aspx
online:1

No comments:

Post a Comment