Rails – 如何检查在线用户?

检查页面上当前在线用户数的最佳方法是什么?

最简单的方法是将last_online时间戳添加到User模型,然后为名为online_now的用户定义范围

class User < ActiveRecord::Base def self.online_now where("last_online > ?", 15.minutes.ago) end end 

留在Redis

就像Yuri Barbashow的 回答一样,但使用Redis ( 对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 

的Gemfile

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

设为online

 # 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返回匿名

设为online

 # 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 | 设置 | 存在 | 到期 | 扫描 | scan_each | redis-rb | hiredis | 初学者的好介绍