原文来自:http://flask.pocoo.org/snippets/71/
功能需求:统计10分钟内在线用户数。
实现思路:利用Redis的Sets数据格式,以unix时间戳(秒)除以60的分钟数作为Redis的Key,value就是用户唯一标志(如id)的列表。当有新用户进来时,就将用户id加入当前这一分钟的队列里面去,并且将此key的超时设置为10分钟。
原文:
You can take the current time since 1970 in seconds, divide it by 60 and build a key based on that, then add a user to that set. Make the set expire after the maximum number of seconds you give a user in activity and when you want to query all active users you just build a union of the keys of the last N minutes.
主要代码:
from redis import Redis redis = Redis() import time from datetime import datetime ONLINE_LAST_MINUTES = 5 def mark_online(user_id): now = int(time.time()) expires = now + (app.config['ONLINE_LAST_MINUTES'] * 60) + 10 all_users_key = 'online-users/%d' % (now // 60) user_key = 'user-activity/%s' % user_id p = redis.pipeline() p.sadd(all_users_key, user_id) p.set(user_key, now) p.expireat(all_users_key, expires) p.expireat(user_key, expires) p.execute() ''' 根据用户最新活动时间,来判断该用户是否在线 ''' def get_user_last_activity(user_id): last_active = redis.get('user-activity/%s' % user_id) if last_active is None: return None return datetime.utcfromtimestamp(int(last_active)) ''' 列出所有在线用户 ''' def get_online_users(): current = int(time.time()) // 60 minutes = xrange(app.config['ONLINE_LAST_MINUTES']) return redis.sunion(['online-users/%d' % (current - x) for x in minutes]) ''' 将用户(标志为request.remote_addr)标记为在线状态 ''' @app.before_request def mark_current_user_online(): mark_online(request.remote_addr)