2011-01-23 84 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);