Get a list of all active sessions in ASP.NET
Asked Answered
L

3

19

I know what user is logged in with the following line of code:

Session["loggedInUserId"] = userId;

The question I have is how do I know what users are logged in so that other users can see what users are currently logged in.

In other words can I get all "loggedInUserId" sessions that are active?

Lebaron answered 13/1, 2012 at 16:50 Comment(2)
possible duplicate of List all active ASP.NET SessionsWeakkneed
Does this answer your question? List all active ASP.NET SessionsDiaspora
L
23

I didn't try rangitatanz solution, but I used another method and it worked just fine for me.

private List<String> getOnlineUsers()
    {
        List<String> activeSessions = new List<String>();
        object obj = typeof(HttpRuntime).GetProperty("CacheInternal", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
        object[] obj2 = (object[])obj.GetType().GetField("_caches", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(obj);
        for (int i = 0; i < obj2.Length; i++)
        {
            Hashtable c2 = (Hashtable)obj2[i].GetType().GetField("_entries", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(obj2[i]);
            foreach (DictionaryEntry entry in c2)
            {
                object o1 = entry.Value.GetType().GetProperty("Value", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(entry.Value, null);
                if (o1.GetType().ToString() == "System.Web.SessionState.InProcSessionState")
                {
                    SessionStateItemCollection sess = (SessionStateItemCollection)o1.GetType().GetField("_sessionItems", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(o1);
                    if (sess != null)
                    {
                        if (sess["loggedInUserId"] != null)
                        {
                            activeSessions.Add(sess["loggedInUserId"].ToString());
                        }
                    }
                }
            }
        }
        return activeSessions;
    }
Lebaron answered 13/1, 2012 at 20:49 Comment(6)
Very cool! NB this should be optimized so that the reflection is cached. Also of course both of our solutions will fail if the site is being run over multiple web nodes.Lesleylesli
Good post. I am getting an error in line object[] obj2 = (object[])obj.GetType().GetField("_caches", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(obj); in iis6 (Windows server 2003). Working fine in windows XP and windows 7.Fantasist
And if I need the SessionID for each active session?Gord
Some comments to explain what is going on were not badCounterespionage
Please try to use meaningful variable names... obj and obj2 don't cut it ;)Cavafy
Is it still valid? At this line object obj I'm getting error System.Type.GetProperty(...) returned nullIroquoian
L
6

There is a solution listed in this page List all active ASP.NET Sessions

private static List<string> _sessionInfo;
private static readonly object padlock = new object();

public static List<string> Sessions
{
        get
        {
            lock (padlock)
            {
                if (_sessionInfo == null)
                {
                    _sessionInfo = new List<string>();
                }
                return _sessionInfo;
            }
        }
  }

    protected void Session_Start(object sender, EventArgs e)
    {
        Sessions.Add(Session.SessionID);
    }
    protected void Session_End(object sender, EventArgs e)
    {
        Sessions.Remove(Session.SessionID);
    }

Basically it just tracks sessions into a List that you can use to find out information about. Can really store anything into that that you really want to - Usernames or whatever.

I don't htink there is anything at the ASP .net layer that does this already?

Lesleylesli answered 13/1, 2012 at 16:52 Comment(5)
Just a little reminder: IIRC the Session_End event is only raised when using the InProcess session state. When using StateServer or SQL server for session state, that's not the case which means that objects will never be removed from your _sessionInfo collection. Therefore you would have to implement some "timeout" mechanism which removes timed-out sessions.Guyette
My understanding is that List.Add/Remove are not thread-safe. So don't you need to lock (padlock) on these operations?Sansom
Yeah that sounds correct. Could also use one of these new ConcurrentCollections I guess.Lesleylesli
I'm sorry, but what exactly is the padlock object for?Brigantine
@MatheusRocha It simply runs all the code in the lock as synchronous, for one thread/context at a time. The name padlock can be anything you like ie. banana or lockerBeefeater
L
-1
foreach (var item in Session.Contents)
{Response.Write(item + " : " + Session[(string)item] + "<br>");}
Laughton answered 30/1, 2023 at 23:31 Comment(1)
This accesses the current session items, not a full list of sessions.Cholecalciferol

© 2022 - 2024 — McMap. All rights reserved.