ruby-on-rails - Rails - 如何检查在线用户?

标签 ruby-on-rails ruby

检查页面上当前有多少用户的最佳方法是什么?

最佳答案

保存在Redis中

喜欢 Yuri Barbashow 的 answer但使用 Redis ( nice introdution for Rails ):

# config/initializers/redis.rb

$redis_onlines = Redis.new
# it's the simplest way, but i'd recommend:
# $redis_onlines = Redis.new path: "/tmp/redis.sock", db: 15, driver: :hiredis
# => hiredis driver more fast
# => use unix domain socket if it's possible
# => default db is No.0, but it is better to use a specific database
#    and No.0 leave for testing-development-and-more-and-more

gem 文件

# Gemfile

gem 'redis'
gem 'hiredis' # optional
# don't forget to run `bundle`

设置为在线

# app/controllers/application_controller.rb
after_filter :set_online
# the Rails 4 way is:
# after_action :set_online

private

  # set to online
  def set_online
    if !!current_user
      # using separate Redis database
      # such as $redis_onlines = Redis.new db: 15
      # value not need, only key
      $redis_onlines.set( current_user.id, nil, ex: 10*60 )
      # 'ex: 10*60' - set time to live - 10 minutes
    end
  end

在线吗?

# app/models/user.rb

def online?
  $redis_onlines.exists( self.id )
end

还有小红利(如果你使用单独的 redis 数据库)

# app/cpntrollers/application_controller.rb

def all_who_are_in_touch
  $redis_onlines.keys
  # => [ "123", "234", "1", "23" ]
  # array of ids
end

#UDP1 匿名返工

设置为在线

# app/controllers/application_controller.rb

  def set_online
    if !!current_user
      $redis_onlines.set( "user:#{current_user.id}", nil, ex: 10*60 )
    else
      $redis_onlines.set( "ip:#{request.remote_ip}", nil, ex: 10*60 )
    end
  end

在线吗?

# app/models/user.rb

def online?
  $redis_onlines.exists( "user:#{self.id}" )
end

所有联系的人:

# app/cpntrollers/application_controller.rb

def all_signed_in_in_touch
  ids = []
  $redis_onlines.scan_each( match: 'user*' ){|u| ids << u.gsub("user:", "") }
  ids
end

def all_anonymous_in_touch
  $redis_onlines.scan_each( match: 'ip*' ).to_a.size
end

def all_who_are_in_touch
  $redis_onlines.dbsize
end

#UDP2 建议

  1. 使用 before_filter 而不是 after_filter
# app/controllers/application_controller.rb
  before_filter :set_online # before_action for Rails 4
  1. 如果你看的是匿名的(比如session[:user_id]是当前用户的id)
# app/controllers/session_controller.rb
  before_filter :clear_from_signed_in_touch, only: :destroy
  before_filter :clear_from_anonymous_in_touch, only: :create

  private

    def clear_from_anonymous_in_touch
      $redis_onlines.del( "ip:#{request.remote_ip}" )
    end

    def clear_from_signed_in_touch
      $redis_onlines.del( "user:#{session[:user_id]}" )
    end

后记:Redis | set | exists | expire | scan | scan_each | redis-rb | hiredis | nice introduction for beginners

关于ruby-on-rails - Rails - 如何检查在线用户?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10805479/

相关文章:

ruby-on-rails - 如何在 os x 10.8.3 上安装 rmagic 2.12.2

javascript - ajax 'delete' Rails 按钮

ruby - 从派生类方法调用基类方法

javascript - gmap4rails 在本地工作但不显示在 heroku 上

ruby-on-rails - 在生产环境中使用 Capistrano 的 Rails 多环境凭证 : How to set it up?

javascript - Rails 4 - 强制浏览器执行 javascript 响应而不是显示文本

ruby-on-rails - 在 Rails 中通过 current_user 访问数据库字段

ruby - 使用column_names时有没有办法减少counter_culture gem?

ruby-on-rails - 升级到 ruby​​ 1.9.2 后奇怪的无法要求配置/启动

ruby - 在 Mountain Lion 中构建 gem 时出错