{"id":3170,"date":"2013-10-10T17:13:31","date_gmt":"2013-10-10T09:13:31","guid":{"rendered":"https:\/\/kyle.ai\/blog\/?p=3170"},"modified":"2013-10-10T17:13:32","modified_gmt":"2013-10-10T09:13:32","slug":"%e5%88%a9%e7%94%a8redis%e7%bb%9f%e8%ae%a1%e5%9c%a8%e7%ba%bf%e7%94%a8%e6%88%b7%e6%95%b0","status":"publish","type":"post","link":"https:\/\/kyle.ai\/blog\/3170.html","title":{"rendered":"\u5229\u7528Redis\u7edf\u8ba1\u5728\u7ebf\u7528\u6237\u6570"},"content":{"rendered":"<p><span style=\"font-size: small;\">\u539f\u6587\u6765\u81ea\uff1ahttp:\/\/flask.pocoo.org\/snippets\/71\/<\/span><\/p>\n<p><span style=\"font-size: small;\">\u529f\u80fd\u9700\u6c42\uff1a\u7edf\u8ba110\u5206\u949f\u5185\u5728\u7ebf\u7528\u6237\u6570\u3002<\/span><\/p>\n<p><span style=\"font-size: small;\">\u5b9e\u73b0\u601d\u8def\uff1a\u5229\u7528Redis\u7684Sets\u6570\u636e\u683c\u5f0f\uff0c\u4ee5unix\u65f6\u95f4\u6233(\u79d2)\u9664\u4ee560\u7684\u5206\u949f\u6570\u4f5c\u4e3aRedis\u7684Key\uff0cvalue\u5c31\u662f\u7528\u6237\u552f\u4e00\u6807\u5fd7\uff08\u5982id\uff09\u7684\u5217\u8868\u3002\u5f53\u6709\u65b0\u7528\u6237\u8fdb\u6765\u65f6\uff0c\u5c31\u5c06\u7528\u6237id\u52a0\u5165\u5f53\u524d\u8fd9\u4e00\u5206\u949f\u7684\u961f\u5217\u91cc\u9762\u53bb\uff0c\u5e76\u4e14\u5c06\u6b64key\u7684\u8d85\u65f6\u8bbe\u7f6e\u4e3a10\u5206\u949f\u3002<\/span><\/p>\n<p><span style=\"font-size: small;\">\u539f\u6587\uff1a<\/span><\/p>\n<p><span style=\"font-size: small;\">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.<\/span><\/p>\n<p><span style=\"font-size: small;\">\u4e3b\u8981\u4ee3\u7801\uff1a<\/span><\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nfrom redis import Redis\r\nredis = Redis()\r\n\r\nimport time\r\nfrom datetime import datetime\r\n\r\nONLINE_LAST_MINUTES = 5\r\n\r\ndef mark_online(user_id):\r\n    now = int(time.time())\r\n    expires = now + (app.config&#x5B;'ONLINE_LAST_MINUTES'] * 60) + 10\r\n    all_users_key = 'online-users\/%d' % (now \/\/ 60)\r\n    user_key = 'user-activity\/%s' % user_id\r\n    p = redis.pipeline()\r\n    p.sadd(all_users_key, user_id)\r\n    p.set(user_key, now)\r\n    p.expireat(all_users_key, expires)\r\n    p.expireat(user_key, expires)\r\n    p.execute()\r\n\r\n'''\r\n\u6839\u636e\u7528\u6237\u6700\u65b0\u6d3b\u52a8\u65f6\u95f4\uff0c\u6765\u5224\u65ad\u8be5\u7528\u6237\u662f\u5426\u5728\u7ebf\r\n'''\r\ndef get_user_last_activity(user_id):\r\n    last_active = redis.get('user-activity\/%s' % user_id)\r\n    if last_active is None:\r\n        return None\r\n    return datetime.utcfromtimestamp(int(last_active))\r\n\r\n'''\r\n\u5217\u51fa\u6240\u6709\u5728\u7ebf\u7528\u6237\r\n'''\r\ndef get_online_users():\r\n    current = int(time.time()) \/\/ 60\r\n    minutes = xrange(app.config&#x5B;'ONLINE_LAST_MINUTES'])\r\n    return redis.sunion(&#x5B;'online-users\/%d' % (current - x)\r\n                         for x in minutes])\r\n'''\r\n\u5c06\u7528\u6237\uff08\u6807\u5fd7\u4e3arequest.remote_addr\uff09\u6807\u8bb0\u4e3a\u5728\u7ebf\u72b6\u6001\r\n'''\r\n@app.before_request\r\ndef mark_current_user_online():\r\n    mark_online(request.remote_addr)\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u539f\u6587\u6765\u81ea\uff1ahttp:\/\/flask.pocoo.org\/snippets\/71\/ \u529f\u80fd\u9700\u6c42\uff1a\u7edf\u8ba110\u5206\u949f\u5185\u5728\u7ebf [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-3170","post","type-post","status-publish","format-standard","hentry","category-diary"],"_links":{"self":[{"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/posts\/3170","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/comments?post=3170"}],"version-history":[{"count":1,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/posts\/3170\/revisions"}],"predecessor-version":[{"id":3171,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/posts\/3170\/revisions\/3171"}],"wp:attachment":[{"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/media?parent=3170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/categories?post=3170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/tags?post=3170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}