在我的 ASP.NET MVC3 Web 应用程序中,我想添加一条小消息,显示当前浏览该网站的用户数量。
我当前正在使用 Session_Start
和 Session_End
应用程序事件来递增或递减 Global.asax 内的静态属性。
这可行,但一点也不精确。由于我的 session 超时配置为 2000 万,因此更新之间存在巨大的延迟。
有没有更优雅、更精确的方法来做到这一点?
我想过通过 AJAX 调用一个操作,它只是在 window.onbeforeunload
javascript 事件上执行 Session.Abandon()
,但这每次都会被调用用户更改了页面。有没有办法确定用户何时关闭浏览器或离开域?
欢迎任何提示、评论或代码示例!
以下是当前代码的相关部分:
public class MvcApplication : System.Web.HttpApplication
{
public static int UsersConnected { get; set; }
protected void Session_Start(object sender, EventArgs e)
{
Application.Lock();
UsersConnected++;
Application.UnLock();
}
protected void Session_End(object sender, EventArgs e)
{
Application.Lock();
UsersConnected--;
Application.UnLock();
}
...
}
最佳答案
好吧,这有点棘手,但我已经提出了一个“好的”解决方案。
首先,我在 Global.asax 中创建了一个静态字典,它将存储客户端的 IP 地址及其上次投票日期。
public class MvcApplication : System.Web.HttpApplication
{
public static Dictionary<string, DateTime> ConnectedtUsers { get; set; }
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ConnectedtUsers = new Dictionary<string, DateTime>();
}
...
}
然后,在我的 CommonsController 中,我创建了此操作,它将添加新客户端、删除过去 30 秒内未轮询的客户端并更新已注册客户端的轮询日期:
public class CommonsController : Controller
{
...
public JsonResult UserConnected()
{
string ip = Request.UserHostAddress;
if (MvcApplication.ConnectedtUsers.ContainsKey(ip))
{
MvcApplication.ConnectedtUsers[ip] = DateTime.Now;
}
else
{
MvcApplication.ConnectedtUsers.Add(ip, DateTime.Now);
}
int connected = MvcApplication.ConnectedtUsers.Where(c => c.Value.AddSeconds(30d) > DateTime.Now).Count();
foreach (string key in MvcApplication.ConnectedtUsers.Where(c => c.Value.AddSeconds(30d) < DateTime.Now).Select(c => c.Key))
{
MvcApplication.ConnectedtUsers.Remove(key);
}
return Json(new { count = connected }, JsonRequestBehavior.AllowGet);
}
}
最后,在我的布局页面上,添加了此代码,该代码将每 30 秒调用我的操作并在跨度中输出结果:
<span id="connectedUsers"></span>
<script type="text/javascript">
function PollUsers()
{
$(function() {
$.getJSON("/Commons/UserConnected", function(json){ $('#connectedUsers').text(json.count + " user(s) connected")});
});
}
setInterval(PollUsers, 30000);
</script>
可能不是那么精确,也可能不是那么优雅,但它确实有效。当然,来自同一 IP 的多个用户也算作一个用户。但这是迄今为止我尝试过的最佳解决方案。
关于ASP.NET MVC3 : Connected clients count,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11592741/