检查用户是否实时在线

时间:2016-09-12 20:06:15

标签: ruby-on-rails ruby-on-rails-5 actioncable

我想检查用户此时是否在线。这应该显示在用户个人资料中。

我在application_controller

中得到了这个
after_filter :user_activity

private

  def user_activity
    current_user.try :touch
  end

我在user-model

中对此进行了定义
def online?
 updated_at > 10.minutes.ago
end

如果用户在线,我可以查看视图:(HAML)

- if @user.online?

这样可行,但总是会重新加载更新此信息所需的页面。 它如何成为实时检查? 也许使用ActionCable?

PS:使用devise

4 个答案:

答案 0 :(得分:5)

是的,可以使用Action Cable。 Rails指南中有(一半)示例:Action Cable Overview -- 6.1 Example 1: User Appearance

基本上,您创建了AppearanceChannel并且每个用户都订阅了它。订阅会调用appear的{​​{1}}功能,然后可以将其广播出去(例如,向其他用户显示在线状态),通常是通过后台作业current_user。 (我刚刚开始研究这个问题)。

答案 1 :(得分:2)

我尝试使用Action Cable示例,但是我遇到了一些问题(当我重新启动服务器时没有调用.disappear,当用户打开多个标签等时也很难处理......)

所以最简单的工作解决方案是每隔5分钟调用服务器一次,就像在javascript中一样:

setInterval(function(){
  var xhttp = new XMLHttpRequest();
  xhttp.open("GET", "/i_am_still_here", true);
  xhttp.send();
}, 5*60*1000);

等控制器

def i_am_still_here
  current_user.update(last_seen_at:DateTime.now)
end

等User.rb

def is_online?
  last_seen_at > 5.minutes.ago
end

答案 2 :(得分:1)

最好的方法是使用客户端技术。服务器只能根据用户对服务器的最后请求知道用户是否处于活动状态。

用户可能在没有将请求发送到服务器的情况下浏览您的应用,并且会根据您的时间限制显示为不在线(即使它们处于活动状态)。

考虑使用websockets来完成此任务,无论是使用JavaScript,Obj-C / Swift还是Java。

答案 3 :(得分:0)

是的,正如诺亚(Noah)写道,客户端是这样做的自然选择。客户端可以按选定的间隔启动数据库更新,以指示它们存在。检测另一个用户的存在涉及检查他们的更新是否足够新鲜。

页面加载似乎是强制性的,但是使用ajax并不会占用太多资源。您甚至可以(而且应该)为ajax目标页面创建特殊的布局,而不会像CSS和js那样增加负担。

我在视图中使用此javascript(依赖项:jquery):

function update_presence() {
  $.ajax({
    url:  '/presence',
    // data: { "my_get_param": "whatever" },
    type: 'GET'
    })
    .done(function(response){
      $('div#last-seen').html(response);
    })
}
// run it every 30 seconds
setInterval(update_presence, 30000)

然后像往常一样定义路线,动作和视图。在控制器中的presence操作中,我调用了helper函数:

update_presence(current_user)

helper函数是一个单行代码:

def update_presence(user)
  user.update_attribute(:last_seen, DateTime.now)
end

在视图中,您可以显示一些可能需要的结果。我的javascript(请参见上文)在页面上显示结果,但这仅用于测试。

<%= current_user.last_seen %>

在模型中,我有一种检查状态的方法:

def is_present?
  self.last_seen  > 2.minutes.ago
end

因此,对于任何用户,您都可以致电@user.is_present?。但是要动态更新网页上的状态指示器,我认为还需要另一个ajax调用。