List all active ASP.NET Sessions

后端 未结 9 1855
情话喂你
情话喂你 2020-11-28 22:39

How can I list (and iterate through) all current ASP.NET sessions?

9条回答
  •  遥遥无期
    2020-11-28 23:02

    Here's a WebForms/Identity example that gets a list of the logged on users active within the last 30 minutes.

    The answer below works for a single web server, and the cache will be lost if the application restarts. If you want to persist the data and share it between servers in a web farm, this answer might be of interest.

    In Global.asa.cs:

    public static ActiveUsersCache ActiveUsersCache { get; } = new ActiveUsersCache();
    

    and

    protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        if (User != null && User.Identity.IsAuthenticated)
        {
            // Only update when the request is for an .aspx page
            if (Context.Handler is System.Web.UI.Page)
            {
                ActiveUsersCache.AddOrUpdate(User.Identity.Name);
            }
        }
    }
    

    The add these couple of classes:

    public class ActiveUsersCache
    {
        private readonly object padlock = new object();
        private readonly Dictionary cache = new Dictionary();
        private DateTime lastCleanedAt;
    
        public int ActivePeriodInMinutes { get; } = 30;
        private const int MinutesBetweenCacheClean = 30;
    
        public List GetActiveUsers()
        {
            CleanCache();
    
            var result = new List();
            lock (padlock)
            {
                result.AddRange(cache.Select(activeUser => new ActiveUser {Name = activeUser.Key, LastActive = activeUser.Value}));
            }
            return result;
        }
    
        private void CleanCache()
        {
            lastCleanedAt = DateTime.Now;
            var cutoffTime = DateTime.Now - TimeSpan.FromMinutes(ActivePeriodInMinutes);
            lock (padlock)
            {
                var expiredNames = cache.Where(au => au.Value < cutoffTime).Select(au => au.Key).ToList();
                foreach (var name in expiredNames)
                {
                    cache.Remove(name);
                }
            }
        }
    
        public void AddOrUpdate(string userName)
        {
            lock (padlock)
            {
                cache[userName] = DateTime.Now;
            }
    
            if (IsTimeForCacheCleaup())
            {
                CleanCache();
            }
        }
    
        private bool IsTimeForCacheCleaup()
        {
            return lastCleanedAt < DateTime.Now - TimeSpan.FromMinutes(MinutesBetweenCacheClean);
        }
    }
    
    public class ActiveUser
    {
        public string Name { get; set; }
    
        public DateTime LastActive { get; set; }
    
        public string LastActiveDescription
        {
            get
            {
                var timeSpan = DateTime.Now - LastActive;
                if (timeSpan.Minutes == 0 && timeSpan.Seconds == 0)
                    return "Just now";
                if (timeSpan.Minutes == 0)
                    return timeSpan.Seconds + "s ago";
                return $"{timeSpan.Minutes}m  {timeSpan.Seconds}s ago";
            }
        }
    }
    

    Finally, in the page where you want to display the active users, display the results:

    UserRepeater.DataSource = Global
        .ActiveUsersCache.GetActiveUsers().OrderByDescending(u => u.LastActive);
    UserRepeater.DataBind();
    

提交回复
热议问题