forgeplus/app/libs/user_online.rb

90 lines
2.8 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module UserOnline
class << self
redis_config = YAML.load_file(Rails.root.join('config', 'redis.yml'))
if redis_config.present?
redis_url = redis_config[Rails.env]['url']
$redis = Redis.new({:url=>redis_url})
else
$redis = Rails.cache.data
end
def login(user_id)
set_bit(user_id, 1)
end
def logout(user_id)
if Rails.cache.is_a?(ActiveSupport::Cache::RedisStore)
now = Time.now()
keys = []
(1..5).each do |i|
key = (now - i.minutes).strftime("%H-%M")
keys << "cache:online_user_#{key}"
set_bit_and_expire(cache_key, user_id, 0) unless $redis.ttl(cache_key) == -2
end
end
set_bit(user_id, 0)
end
def set_bit(user_id, flag)
if $redis.ttl(cache_key) == -2
# 如果key不存在
set_bit_and_expire(cache_key, user_id, flag)
else
if $redis.ttl(cache_key) ==-1
# 可以存在,但过期时间没关联
# 这种情况大概率是并发原因导致对相应key设置过期时跳过了。所以删除并重新设置过期时间
$redis.del(cache_key)
set_bit_and_expire(cache_key, user_id, flag)
end
# 统计当前时间下前5分钟的活跃人数
$redis.setbit(cache_key, user_id, flag)
end
end
def set_bit_and_expire(cache_key, user_id, flag)
$redis.setbit(cache_key, user_id, flag)
# $redis.setbit(last_cache_key, user_id, flag)
# 现在统计5分钟在线人数这里设置6分钟过期目的是统计当前时刻的前5分钟
$redis.expire(cache_key, 6 * 60)
end
def count
if Rails.cache.is_a?(ActiveSupport::Cache::RedisStore)
now = Time.now()
keys = []
(0..4).each do |i|
key = (now - i.minutes).strftime("%H-%M")
keys << "cache:online_user_#{key}"
end
# 防止每个分钟数据有重复,所以去重去除
$redis.bitop("OR", "daiao", keys)
$redis.bitcount("daiao")
else
0
end
end
def cache_key
if Rails.cache.is_a?(ActiveSupport::Cache::RedisStore)
"cache:online_user_#{Time.now().strftime("%H-%M")}"
else
raise '请配置config.cache_store = redis_store'
end
end
def last_cache_key
if Rails.cache.is_a?(ActiveSupport::Cache::RedisStore)
# 如设置5分钟内即300秒有请求的用户视为在线, 则最大会统计到10分钟内有活动用户
# TODO 更精确时长
begin_hour = Time.now.beginning_of_hour
minutes_piece = (Time.now - begin_hour) / (60 * 5)
time = begin_hour.since((minutes_piece.to_i - 1) * (60 * 5)).strftime("%H-%M")
"cache:online_user_#{time}"
else
raise '请配置config.cache_store = redis_store'
end
end
end
end