2011-01-23 85 views
3

我的应用程序中有一个页面,它总是显示在线用户的更新列表。 现在,以保持列表存储在应用程序对象 - 更新,我做以下步骤在asp.net中获取在线用户列表mvc

  1. 将用户添加到列表时,登录上注销

  2. 删除用户然后为了处理浏览器关闭/导航状态,我有一个时间戳和集合中的用户名 每90秒ajax调用更新时间戳。

问题: 我需要一些东西来清理这个名单每120秒删除旧的时间戳的条目。

如何在我的Web应用程序中执行此操作?即每2分钟调用一次功能。 PS:我想用调度器每2分钟调用一次web服务,但主机环境不允许任何调度。

回答

1

这是白象解决方案。

而不是在应用程序对象中维护此列表,而是在数据库中维护此列表。然后,您可以使用数据库作业定期处理此列表。在此对象上建立SQL通知,以便每次清除此列表时,都会在应用程序中刷新数据。

+0

1.我不太熟悉SQL的功能,因为我使用asp.net,就像你提到的那样。我在SQL方面的知识很大程度上局限于DDL,DML等。那么,你能解释还是提供一个能帮助我的链接? – maX 2011-01-24 12:14:00

+0

2.我确实想过使用db。但问题是会有太多的点击。所有客户端每90秒更新一次ajax调用。 – maX 2011-01-24 13:26:39

5

在您的局部视图,您的账户控制器

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"); 
    } 

@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> 
    } 
} 

使这个局部视图,当用户身份登录。

使用这个脚本调用以往90秒

<script type="text/javascript"> 
    $(function() { 
     setInterval(loginDisplay, 90000); 
    }); 

    function loginDisplay() { 
     $.post("/Account/getLoginUser", null, function (data) { 

     }); 
    } 
</script> 
+0

我知道这不是你问题的真正答案,但是当用户登录和分享时,可能会帮助你解决问题。 – dev 2013-01-16 18:18:32

+0

为什么您在缓存而不是应用程序中还原用户?因为高速缓存是一个临时存储。 – 2015-05-04 04:05:34

1

使用AJAX来发送“我还在网上”在每封邮件服务器30秒。这是找到真正在线的人的最佳方式。

6

在全局过滤器中执行以下操作。

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); 
     } 

    } 
} 

检索用户列表

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; 

    } 
} 

不要忘记注册您在Global.asax中进行筛选。将应用设置为关闭状态可能是一个好主意。

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

还可以在注销时删除用户以更加准确。

SecurityHelper.GetLoggedInUsers().Remove(WebSecurity.CurrentUserName);