C# asp.net MVC:何时更新 LastActivityDate?
我正在使用 ASP.NET MVC 并创建一个公共网站。我需要跟踪在线用户。我发现 asp.net 中执行此操作的标准方法是跟踪 LastActivityDate
。我的问题是我什么时候应该更新这个?
如果我每次用户点击某个地方时都更新它,我会感觉到性能下降。然而,如果我不这样做,那些只上网冲浪的人将被列为离线。
在 ASP.NET MVC 中执行此操作的最佳方法是什么?
I'm using ASP.NET MVC and creating a public website. I need to keep track of users that are online. I see that the standard way in asp.net of doing this is to keep track of LastActivityDate
. My question is when should I update this?
If I update it every time the users clicks somewhere, I will feel a performance draw back. However if I do not do that, people that only surf around will be listed as offline.
What is the best way to do this in asp.net MVC?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
为什么不将 LastActivityDate 的更新实现为异步调用?这样您就可以触发更新并继续处理。
Why not implement the update to LastActivityDate as an asynchronous call? That way you can fire the update and continue processing.
正如 @Jab 所说,只需实现它,如果您将来将其视为性能问题 - 那么就处理它。
这就是我在应用程序中的做法:
我没有遇到任何性能问题。
HTH,
查尔斯
As @Jab says, just implement it and if you see it as a performance issue in the future - deal with it then.
This is how I've done it in my application:
I haven't had any problems with performance.
HTHs,
Charles
我将其放入一个特殊的队列中,该队列仅允许给定键之一位于队列中(并在本例中使用 userId 作为键)。然后我有一个低优先级线程通过该队列进行数据库更新。因此,用户不会减慢速度,一个用户在一秒钟内执行 100 次更新不会造成任何伤害。如果它成为一个问题,我会将这些更新变成针对数据库的批量更新,但目前这种方法效果很好。
如果应用程序崩溃,我会丢失几秒钟的最后活动数据,但这没关系。当然,我每次也会更新内存中的 User 对象,以便它反映在 UI 中,即使它尚未进入数据库也是如此。通常在他们收到完整的页面之前它就已经存在了。
I put it into a special queue that allows only one of a given key to be in the queue (and use the userId as the key in this case). Then I have a low priority thread that works its way through this queue doing database updates. Thus no slow down for the user, and one user doing 100 updates in one second doesn't cause any harm. If it ever becomes an issue I'll make those updates into batch updates against the database but for now this approach works just fine.
If the application crashed I'd lose a few seconds of last activity data but that's just fine. Of course I also update the in memory User object every time so that it's reflected in the UI even if it hasn't made its way to the database yet. Typically it's there before they've received the completed page anyway.
如果您使用的是 InProc SessionState,请使用 SessionStateModule.End 事件。当会话状态从底层缓存存储中被逐出时,就会发生这种情况。通常,这种情况会在 20 分钟不活动后发生,您可以在 web.config 中设置时间。
If you are using InProc SessionState, use the SessionStateModule.End event. This happens when the session state is evicted from the underlying cache storage. Typically this happens after 20 minutes of inactivity, you can set the time in web.config.
好问题,也考虑过这个问题,以及这些机制在考虑性能方面的准确性,有几个想法:
1)跟踪上次登录日期
2)使用LastLoginDate +预期的会话长度来设置某种LastOnlineDate,可以用于检查用户是否在线。
Good question, have thought about that too and how accurate these mechanisms can be considering performance, a couple of ideas:
1) Track the the last login date
2) Use the LastLoginDate + the expected session length to set some kind of LastOnlineDate that can be used to check if the user is online.
我认为,如果您在每个请求中获取当前登录的用户并每次更新
LastActivityDate
字段(如果您小心并调用GetUser< /code> 每个 http 请求登录用户的方法)。通过这种方式,您还可以确保用户的数据始终是最新的,例如电子邮件、姓名等,以防他/她更新该数据。
I don't think there is big penalty in performance if you fetch the current logged-in user on every request and update the
LastActivityDate
field every time (if you have care and invoke theGetUser
method for the logged-in user once per http-request). In this way you can also make sure you always have the user's data fresh, like email, name, etc in case he/she updates that data.我在 Global.asax 中尝试了 Charlino 的代码,如下所示,
但是我总是得到
Request.IsAuthenticated
false 。因此,我将代码移至
Site.Master page
中的一个方法,如下所示,我从
Master page
Page_Load
事件调用该方法,然后它起作用了。我使用的是
asp.net Identity
而不是Membership
,但我添加了一个继承于IdentityUser
类的AppUser
类,并且在AppUser
类中,我添加了LastActivityDate 属性
。这是在
WebForms 应用程序
中,而不是在MVC
中。I tried Charlino's code in the Global.asax like this
However I was getting the
Request.IsAuthenticated
false all the time.So I moved the code to a method in my
Site.Master page
like thisI call the method from the
Master page
Page_Load
event, and there it worked.I'm using
asp.net Identity
notMembership
but I added anAppUser
class inheriting from theIdentityUser
class and in theAppUser
class I addedLastActivityDate property
.This is in a
WebForms Applicaction
notMVC
.只需在母版页底部放置一个 ajax javascript 调用即可跟踪此情况。
此时不用担心性能。如果它已实施并且您发现它是一个问题,那么请回过头来寻找更好的解决方案。如此简单的事情不应该是性能问题。
就像谷歌分析一样思考一下。它位于数百万个页面的底部,对这些网站的用户体验几乎没有影响。
Just put an ajax javascript call at the bottom of your master page to track this.
Don't worry about performance at this time. If it's implemented and you see it being a problem then come back to finding a better solution. Something so simple shouldn't be a performance problem.
Just think about it like Google analytics. It sits at the bottom of millions of pages with little to no impact on the user experiences of those sites.
刚刚遇到了同样的问题,这是我对 MVC 用户的回答:
这个想法是为每个页面加载触发 Membership.GetUser("..", true) 。这将自动更新 LastActivityDate。
我将其放在“RegisterGlobalFilters”下的 global.asax 中:
我创建了一个如下所示的新类:
Just ran into the same problem, here's my answer for MVC users:
The idea is to trigger Membership.GetUser("..", true) for every page load. This will automatically update the LastActivityDate.
I put this in my global.asax under "RegisterGlobalFilters":
I created a new class that looks like this:
我开始使用 SimpleMembershipProvider。它非常简单,不再需要
LastActivityDate
跟踪。所以我不得不自己动手。我刚刚在用户表中添加了一个
LastActivityDate
列,一切顺利...遵循 @Jab 的提示< /a> 并在 ASP.NET MVC 应用程序中使用
_Layout.cshtml
页面(母版页),我在 jQuery 的帮助下完成了此操作:这是操作方法:
仅 133 毫秒 (YMMV) :- )
I started using the SimpleMembershipProvider. It's so simple that there's no more
LastActivityDate
tracking. So I had to roll my own.I just added a
LastActivityDate
column in the Users table and was good to go...Following @Jab's tip and using the
_Layout.cshtml
page (master page) in an ASP.NET MVC app, I did this with the help of jQuery:Here's the action method:
Only 133ms (YMMV) :-)