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?

hhh3112
  • 2,167
  • 10
  • 36
  • 55
  • 2
    possible duplicate of [List all active ASP.NET Sessions](http://stackoverflow.com/questions/1470334/list-all-active-asp-net-sessions) – Chris Moschini May 06 '13 at 21:01
  • Does this answer your question? [List all active ASP.NET Sessions](https://stackoverflow.com/questions/1470334/list-all-active-asp-net-sessions) – The_Black_Smurf Sep 29 '20 at 11:49

3 Answers3

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;
    }
Leyu
  • 2,687
  • 2
  • 23
  • 27
hhh3112
  • 2,167
  • 10
  • 36
  • 55
  • 1
    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. – Dave Walker Jan 16 '12 at 09:43
  • 4
    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. – TechDo Nov 20 '12 at 11:02
  • And if I need the SessionID for each active session? – Bergkamp Jun 12 '15 at 14:43
  • Some comments to explain what is going on were not bad – Mohammed Noureldin Jun 25 '18 at 22:28
  • 2
    Please try to use meaningful variable names... obj and obj2 don't cut it ;) – zukanta Apr 24 '19 at 17:20
  • 1
    Is it still valid? At this line ```object obj``` I'm getting error ```System.Type.GetProperty(...) returned null``` – rd1218 Dec 08 '22 at 15:03
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?

Community
  • 1
  • 1
Dave Walker
  • 3,498
  • 1
  • 24
  • 25
  • 7
    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. – M4N Jan 13 '12 at 18:54
  • 2
    My understanding is that `List.Add/Remove` are not thread-safe. So don't you need to `lock (padlock)` on these operations? – Paul B. Oct 09 '14 at 09:18
  • Yeah that sounds correct. Could also use one of these new ConcurrentCollections I guess. – Dave Walker Oct 17 '14 at 11:58
  • I'm sorry, but what exactly is the `padlock` object for? – Matheus Rocha May 07 '18 at 01:04
  • 1
    @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 `locker` – Pierre Apr 10 '23 at 07:37
-1
foreach (var item in Session.Contents)
{Response.Write(item + " : " + Session[(string)item] + "<br>");}
mo fa
  • 33
  • 4