maX*_*maX 3 asp.net asp.net-mvc
我的应用程序中有一个页面,它总是显示更新的在线用户列表.现在,为了保持存储在应用程序对象中的列表更新,我执行以下步骤
登录时将用户添加到列表中
注销时删除用户
然后为了处理浏览器关闭/导航的情况,我有一个时间戳和集合中的用户名每隔90秒调用一次ajax更新时间戳.
问题:我需要每隔120秒清理一次该列表,以删除带有旧时间戳的条目.
如何在我的Web应用程序中执行此操作?即每2分钟调用一次函数.
PS:我想过使用调度程序每2分钟调用一次web服务,但托管环境不允许任何调度.
在全局过滤器中执行以下操作.
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
检索用户列表
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;
}
}
Run Code Online (Sandbox Code Playgroud)
不要忘记在global.asax中注册过滤器.有一个应用程序设置来关闭它可能是一个好主意.
GlobalFilters.Filters.Add(new TrackLoginsFilter());
Run Code Online (Sandbox Code Playgroud)
还要在注销时删除用户以使其更准确.
SecurityHelper.GetLoggedInUsers().Remove(WebSecurity.CurrentUserName);
Run Code Online (Sandbox Code Playgroud)
在您的帐户控制器中
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");
}
Run Code Online (Sandbox Code Playgroud)
在你的局部视图中.
@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>
}
}
Run Code Online (Sandbox Code Playgroud)
用户登录时呈现此部分视图.
使用此脚本调用90秒
<script type="text/javascript">
$(function () {
setInterval(loginDisplay, 90000);
});
function loginDisplay() {
$.post("/Account/getLoginUser", null, function (data) {
});
}
</script>
Run Code Online (Sandbox Code Playgroud)
这是白象解决方案。
不要在应用程序对象中维护此列表,而是在数据库中维护此列表。然后,您可以使用数据库作业定期处理该列表。在此对象上建立 SQL 通知,以便每次清除此列表时,您都可以在应用程序中获得刷新的数据。
| 归档时间: |
|
| 查看次数: |
13767 次 |
| 最近记录: |