我正在尝试计算特定页面上的当前查看者。我需要将此计数存储在DB中。主要问题是用户离开页面后清理。
用户是匿名的。每个活动用户每5秒发送一次AJAX请求。
最好的算法是什么?有什么建议吗?
UPD:我正在尝试减少对数据库的查询量,因此,我认为, 虽然我可以从代码中以其他方式访问它。
答案 0 :(得分:5)
甚至不考虑将其存储在数据库中,您的应用程序将会非常慢。
因此使用Cache进行此类操作。
要计算人数,我会说:
为每个匿名用户分配一个随机ID并将其存储在他的会话中
在您的ajax电话中发送ID
使用[{ :user_id, :latest_ping }, {} ]
在缓存中存储哈希数组(为每个页面创建缓存var)
删除看似太旧的数组元素
您的解决方案:用户数量=数组中元素的数量
答案 1 :(得分:2)
如果以某种方式将用户存储在数据库中,则可以在users表中存储last_seen_at
字段,并使用Time.now
为用户发送的每个AJAX请求更新该字段。
要显示您当前拥有的用户数,您只需执行以下查询:
@user_count = User.where("last_seen_at < ?", 5.seconds.ago).count
如果你想清理旧用户,我建议你运行某种cron作业,或使用whenever
gem或类似的东西,定期删除所有未被查看过的用户一段时间。
答案 2 :(得分:1)
我建议您创建一个模型,其中包含您使用每个AJAX心跳请求保存或更新的唯一键(cookie-id或其他内容)。
然后你有一个会话控制器,看起来像这样:
def create
ActiveUser.where(:cookie => params[:id]) || ActiveUser.new
ActiveUser.cookie = prams[:id]
ActiveUser.timestamp = Time.now
ActiveUser.save
end
您的活跃用户数仅为SELECT COUNT(*) FROM ActiveUsers WHERE timestamp > NOW() - 5
或类似内容。
答案 3 :(得分:0)
Martin Frost走在正确的轨道上。有#touch
方法更新last_seen_at
:user.touch(:last_seen_at)
但是更新用户而不必从数据库中获取模型会更有效:
> User.update_all({:last_seen_at => Time.now}, {:id => params[:user_id})
SQL (3.1ms) UPDATE "users" SET "last_seen_at" = '2011-11-17 12:37:46.863660' WHERE "users"."id" = 27
=> 1