在我的ASP.NET MVC3 Web应用程序中,我想添加一条显示当前正在浏览该站点的用户数量的小消息。
我目前正在使用Session_Start
和Session_End
应用程序事件来增加或减少Global.asax中的静态属性。
这有效,但根本不准确。由于我的会话超时配置为20mn,因此更新之间会有很大的延迟。
有更优雅,更精确的方法吗?
我曾想过通过AJAX调用一个动作,它只对Session.Abandon()
javascript事件window.onbeforeunload
进行调用,但每次用户更改页面时都会调用它。有没有办法确定用户何时关闭浏览器或离开域?
欢迎任何提示,评论或代码示例!
以下是当前代码的相关部分:
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();
}
...
}
答案 0 :(得分:2)
好的,这有点棘手,但我已经找到了一个“好的”解决方案。
首先,我在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的多个用户将计入一个用户。但这是迄今为止我尝试过的最佳解决方案。
答案 1 :(得分:0)
你可以在卸载体事件上从javascript调用webmethod。 http://www.codeproject.com/Tips/89661/Execute-server-side-code-on-close-of-a-browser 最好的问候