get a list of online users in asp.net mvc

前端 未结 4 474
走了就别回头了
走了就别回头了 2020-12-09 00:46

I have a page in my application which always shows updated list of online users. Now, to keep the list-which is stored in application object- updated, i do the below steps

相关标签:
4条回答
  • 2020-12-09 01:24

    In your Account Controller

       public ActionResult Login(LoginModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (Membership.ValidateUser(model.UserName, model.Password))
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                    if (HttpRuntime.Cache["LoggedInUsers"] != null) //if the list exists, add this user to it
                    {
                        //get the list of logged in users from the cache
                        List<string> loggedInUsers = (List<string>)HttpRuntime.Cache["LoggedInUsers"];
                        //add this user to the list
                        loggedInUsers.Add(model.UserName);
                        //add the list back into the cache
                        HttpRuntime.Cache["LoggedInUsers"] = loggedInUsers;
                    }
                    else //the list does not exist so create it
                    {
                        //create a new list
                        List<string> loggedInUsers = new List<string>();
                        //add this user to the list
                        loggedInUsers.Add(model.UserName);
                        //add the list into the cache
                        HttpRuntime.Cache["LoggedInUsers"] = loggedInUsers;
                    }
                    if (!String.IsNullOrEmpty(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
    
                        return RedirectToAction("Index", "Home");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "The user name or password provided is incorrect.");
                }
            }
    
            // If we got this far, something failed, redisplay form
            return View(model);
        }
    
    
        public ActionResult LogOff()
        {
            string username = User.Identity.Name; //get the users username who is logged in
            if (HttpRuntime.Cache["LoggedInUsers"] != null)//check if the list has been created
            {
                //the list is not null so we retrieve it from the cache
                List<string> loggedInUsers = (List<string>)HttpRuntime.Cache["LoggedInUsers"];
                if (loggedInUsers.Contains(username))//if the user is in the list
                {
                    //then remove them
                    loggedInUsers.Remove(username);
                }
                // else do nothing
            }
            //else do nothing
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");
        }
    

    in your partial view.

    @if (HttpRuntime.Cache["LoggedInUsers"] != null)
    {
        List<string> LoggedOnUsers = (List<string>)HttpRuntime.Cache["LoggedInUsers"];
        if (LoggedOnUsers.Count > 0)
        {
        <div class="ChatBox">
            <ul>
                @foreach (string user in LoggedOnUsers)
                {
                    <li>
                        <div class="r_row">
                           <div class="r_name">@Html.Encode(user)</div>
                        </div>
                    </li>
                }
            </ul>
        </div>
        }
    }
    

    render this partial view when user log in.

    use this script call ever 90 second

    <script type="text/javascript">
        $(function () {
            setInterval(loginDisplay, 90000);
        });
    
        function loginDisplay() {
            $.post("/Account/getLoginUser", null, function (data) {
    
            });
        }
    </script>
    
    0 讨论(0)
  • 2020-12-09 01:26

    Use Ajax to send "I am still online" message to the server in every 30 seconds. This is the best way to find who is really online.

    0 讨论(0)
  • 2020-12-09 01:33

    Here is the white elephant solution.

    Instead of maintaining this list in application object, maintain this list in database. Then you can use database jobs to work on this list periodically. Establish SQL notification on this object so that everytime this list is purged you get refreshed data in your application.

    0 讨论(0)
  • 2020-12-09 01:38

    Do the following inside a global filter.

    public class TrackLoginsFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            Dictionary<string, DateTime> loggedInUsers = SecurityHelper.GetLoggedInUsers();
    
            if (HttpContext.Current.User.Identity.IsAuthenticated )
            {
                if (loggedInUsers.ContainsKey(HttpContext.Current.User.Identity.Name))
                {
                    loggedInUsers[HttpContext.Current.User.Identity.Name] = System.DateTime.Now;
                }
                else
                {
                    loggedInUsers.Add(HttpContext.Current.User.Identity.Name, System.DateTime.Now);
                }
    
            }
    
            // remove users where time exceeds session timeout
            var keys = loggedInUsers.Where(u => DateTime.Now.Subtract(u.Value).Minutes >
                       HttpContext.Current.Session.Timeout).Select(u => u.Key);
            foreach (var key in keys)
            {
                loggedInUsers.Remove(key);
            }
    
        }
    }
    

    To retrieve the user list

    public static class SecurityHelper
    {
        public static Dictionary<string, DateTime> GetLoggedInUsers()
        {
            Dictionary<string, DateTime> loggedInUsers = new Dictionary<string, DateTime>();
    
            if (HttpContext.Current != null)
            {
                loggedInUsers = (Dictionary<string, DateTime>)HttpContext.Current.Application["loggedinusers"];
                if (loggedInUsers == null)
                {
                    loggedInUsers = new Dictionary<string, DateTime>();
                    HttpContext.Current.Application["loggedinusers"] = loggedInUsers;
                }
            }
            return loggedInUsers;
    
        }
    }
    

    Don't forget to Register you filter in global.asax. It's probably a good idea to have an app setting to switch this off.

    GlobalFilters.Filters.Add(new TrackLoginsFilter());
    

    Also remove users at logoff to be more accurate.

    SecurityHelper.GetLoggedInUsers().Remove(WebSecurity.CurrentUserName);
    
    0 讨论(0)
提交回复
热议问题