12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- /**
- * Redis会话清除器。会话清理暂时不使用。
- *
- * Redis中的会话有效期为40分钟,即自会话中最后一次时间算起,如果40分钟内没有成员发送、读取消息则将此会话从内存中清除。
- * 为减少冲突,每次只清理时间最久的前10个会话。
- *
- * 清理逻辑:首先检查哪些会话是过期的,取得前10个过期会话,然后取得会话中的消息、MUC议题、成员列表、成员信息及客户端状态,将这些内容全部删除。
- *
- * PS: 目前此策略有一个问题:在并发量大的时候,有可能在清理时,刚好用户在登录,此时会发生冲突。
- *
- * author: Sand
- * since: 12/23/2016
- */
- "use strict";
- let RedisModel = require('../redis.model');
- let RedisClient = require('../../repository/redis/redis.client.js');
- let async = require('async');
- let configFile = require('../../include/commons').CONFIG_FILE;
- let config = require('../../resources/config/' + configFile);
- let redis = RedisClient.redisClient().connection;
- let log = require('../../util/log');
- const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
- class SessionCleaner {
- constructor() {
- }
- /**
- * 清理过期会话,但目前不能清理用户信息,因为用户可能在其他活动的会话中,
- * 除非后续有对每个用户做会话引用,便可以在清除会话时根据引用数量清理用户信息,
- * 因此当前有以下内容不清理:
- * users:
- * users:user_id
- * users:user_id:sessions
- * users:user_id:app_status
- * users:user_id:wechat_status
- *
- * @param count 清理多少个
- */
- static cleanExpiredSessions(count) {
- let baseScore = new Date().getMilliseconds() - config.sessionConfig.expireTime;
- let sessionsKey = RedisModel.makeRedisKey(REDIS_KEYS.Sessions);
- redis.zrevrangebyscoreAsync(sessionsKey, baseScore, config.MAX_INT).then(function (sessionIds) {
- if (sessionIds.length > count) {
- sessionIds = sessionIds.splice(count, sessionIds.length - count);
- }
- // 构建对每个会话的清理操作
- let sessionCleanCalls = [];
- sessionIds.forEach(function (sessionId) {
- sessionCleanCalls.push(function (callback) {
- let topicsKey = RedisModel.makeRedisKey(REDIS_KEYS.Topics, sessionId);
- // 清理议题
- redis.zrangeAsync(topicsKey, 0, -1).then(function (topicIds) {
- redis.del(topicIds.forEach(function (topicId) {
- return RedisModel.makeRedisKey(REDIS_KEYS.Topic, topicId);
- }));
- });
- // 清理会话、议题、参与者、消息
- let toDeleteKeys = [REDIS_KEYS.Sessions, REDIS_KEYS.Session, REDIS_KEYS.Topics,
- REDIS_KEYS.SessionParticipantsRole, REDIS_KEYS.SessionParticipants, REDIS_KEYS.Messages, REDIS_KEYS.MessagesByTimestamp];
- redis.del(toDeleteKeys.forEach(function (key) {
- return RedisModel.makeRedisKey(key, sessionId);
- }));
- });
- });
- async.parallel(sessionCleanCalls, function (err, result) {
- if (err) log.error("Clean redis session failed: ", err);
- log.info(result);
- });
- })
- }
- }
- module.exports = SessionCleaner;
|