Getting All Active Web Sessions

A

Atul

Hi,

I am running .NET Framework 2.0 on windows XP SP2. I am stuck in a situation
where I need to find out a list of all active sessions running in IIS for a
web application.

I know that .NET 2.0 has introduced a new class that facilitate this task
very easily, somehow couldnt recall its name.

Any help would be highly appreciated.
Thanks
Atul
 
T

Tim_Mac

hi atul,
you can get the number of active sessions via the performance monitoring
component of windows.
however if you want to track data in the sessions, that you are restricted
to .Net as far as i am aware. i haven't heard of a built-in method to list
active sessions and usernames etc in .Net 2.0.

i've included below the code i use to track user sessions. it's quite
simple, my only requirement is to record who is online, and when they last
accessed a page. I use the Cache object to track sessions because it has
built-in expiry functionality which is needed in cases where the user closes
the browser (instead of clicking 'log-out) and the session won't expire
until the time-out occurs, at which time you no longer have access to the
data in the session, so you can't track who the session belonged to. the
Cache takes care of removing entries automatically after a specified idle
period.



global.asax:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
// update the 'CurrentUser' cached entry for this user
if(Context.User != null && Context.User.Identity != null &&
Context.User.Identity.IsAuthenticated)
{
string key = String.Format("Cache_{0}", Context.User.Identity.Name);
Context.Cache.Remove(key); // just in case it's there already, cache
allows duplicate names
Context.Cache.Add(key, new ObjectPair(User.Identity.Name,
DateTime.Now.ToString("HH:mm:ss")), null, DateTime.Now.AddMinutes(15),
Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
}




Logout.aspx:
private void Page_Load(object sender, System.EventArgs e)
{
string key = String.Format("Cache_{0}", User.Identity.Name);
Context.Cache.Remove(key); // remove from active users list



Active_Users_List.aspx:
private void Page_Load(object sender, System.EventArgs e)
{
this.DataGrid1.DataSource = ActiveUsers;
this.DataGrid1.DataBind();
}

/// <summary>
/// Returns an array of Pair objects, containing the username (First) and
the last access time (Second)
/// </summary>
public static ArrayList ActiveUsers
{
get
{
ArrayList activeUsers = new ArrayList();
IDictionaryEnumerator CacheEnum =
HttpContext.Current.Cache.GetEnumerator();
while (CacheEnum.MoveNext())
{
if(CacheEnum.Current is DictionaryEntry)
{
DictionaryEntry de = (DictionaryEntry)CacheEnum.Current;
if(de.Key.ToString().StartsWith("Cache_"))
{
// the value stores the username and the last access time in a Pair
object
activeUsers.Add(de.Value as ObjectPair);
}
}
}
return activeUsers;
}
}


Last but not least, the ObjectPair class to store the Username/AcessTime
values. there is one in the framework already but it can't be used in a
GridView because it doesn't have properties, only public members. You could
probably use a DictionaryList instead but i vaguely recall some limitations
there.

/// <summary>
/// A class to store a pair of objects. There is a class in System.Web.UI
but this class has fields
/// and not properties, which are necessary for using with a gridview.
/// </summary>
public class ObjectPair
{
private object pFirst, pSecond;

public ObjectPair(object f, object s)
{
this.pFirst = f;
this.pSecond = s;
}
public object First
{
get { return pFirst; }
set { pFirst = value; }
}
public object Second
{
get { return pSecond; }
set { pSecond = value; }
}
}

hope this helps
tim
 
A

Atul

Hi Tim,

Your solution is excellent. It has just one limitation, as you said, if user closes browser simply by clicking "X" or "ALT+F4". In this case, Cache expiration will expire it based on the expiration time, not immediate. I have another suggestion, think about it and tell me if it is ok.
In case if user closes its browser by clicking any of the two ways as I mentioned above, having a javascript code on browser window event Window.Close(). Is it possible to send any message from JavaScript code to Cache object to remove the Key object immediately? I thought of using AJAX here. Is it gonna be helpful?

Anything clicking in your mind.

Regards,
Atul
 
T

Tim_Mac

hi Atul,
i didn't try and cater for all the variations, because they are very difficult to track:

- user closes the browser window via 'X' button in top right corner (javascript can catch this as you point out)
- user navigates to a different web site (window.onbeforeunload can catch this but IE / Firefox only)
- browser crashes / end-task (can't catch this)
- windows shut-down = kill browser (can't catch this, i think)
- user stays on the same page for 30 minutes, you don't know if they are still there or not (unless you have some javascript timer)

if you were to cater for all these situations, in my opinion the result would be a lot of messy, incompatible, and possibly intrusive javascript code, that still isn't going to cover all the scenarios. be my guest if you want to go to all this trouble! the cache/request-based approach covers everything, albeit to the lowest common denominator of "inactivity".

i like javascript but i keep it to an absolute minimum where possible.
tim
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top