ASP.NET MVC3 : Connected clients count

标签 asp.net asp.net-mvc-3 session count

在我的 ASP.NET MVC3 Web 应用程序中,我想添加一条小消息,显示当前浏览该网站的用户数量。

我当前正在使用 Session_StartSession_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/

相关文章:

python - request.session 没有将完整的 querydict 传输到另一个 View

javascript - 数据不是来自 JsonResult Action 到 Javascript 脚本

javascript - 如何将文本框客户端 ID 传递给 JavaScript 函数

asp.net-mvc-3 - MVC 4 - 如何关闭默认的 Error.vbhtml 页面?

javascript - session 不要跨页面保留

php - 我可以将类实例存储在 $_SESSION 空间中吗?

javascript - 使用 "canvas.toblob()!"后文件名发生变化

ASP.NET 控件不会正确对齐

asp.net-mvc - 在 IE 中拖放上传

asp.net-mvc-3 - 多行变量的语法