首页 优化推广 在线用户实体缓存解决方案

在线用户实体缓存解决方案

来源: | 时间:2013/6/11 1:01:31 |

     随着网站访问量的增加,在线用户实体信息的存储方式变得重要起来。存储在线用户的信息一般有这三种方案:

     1、用户的实体信息保存在Session里,简单方便,随着Session的过期用户信息自动过期。

     2、用户信息保存在数据库中,用一个表存储在线的用户信息。

     3、用户信息保存在内存。

     当前项目用的是第一种方法,把用户的实体信息保存在Session中,虽然使用方便,但总感觉很别扭。Discuz!NT使用的是第二种方法,把在线用户标识保存在一个表中,从cookie跟读取用户的ID,并从用户信息表查询该用户的信息,组装到实体中。如果有大量的用户在线同时操作时,这也不是一个很好的解决办法。

     这里选择第三种解决方案,把用户信息保存到内存。

     我们使用Dictionary来存储用户信息,由于Dictionary不是线程安全的,因此需要注意只能单线程更新字典。

     先定义一个保存用户信息的实体:

 

internal class UserEntity<T>
{
    /// <summary>
    /// 用户信息
    /// </summary>
    internal T UserInfo { get; set; }

    /// <summary>
    /// 添加到列表的时间戳
    /// </summary>
    internal DateTime Timestamp { get; set; }
}

     使用泛型包装用户实体,并增加一个时间戳,表示该用户信息添加到内存的时间,过期是根据这个时间来判断的。

     再增加一个在线用户信息管理类:

 

/// <summary>
/// 在线用户缓存管理
/// </summary>
/// <typeparam name="T"></typeparam>
public class UserCacheManager<T>
{
    #region 静态属性
    /// <summary>
    /// 静态用户缓存表
    /// </summary>
    private static Dictionary<long, UserEntity<T>> _UserList = new Dictionary<long, UserEntity<T>>();
    /// <summary>
    /// 过期时间
    /// </summary>
    private static int _ExpiredMinutes = 30;
    /// <summary>
    /// 定时器
    /// </summary>
    private static Timer _Timer = null;
    #endregion

    #region 静态构造函数
    /// <summary>
    /// 静态构造函数
    /// 初始化计时器
    /// </summary>
    static UserCacheManager()
    {
        _Timer = new Timer(new TimerCallback(TimerClear), null, 60000, _ExpiredMinutes × 60000);
    }
    #endregion

    #region 私有方法
    /// <summary>
    /// 清除在线用户
    /// </summary>
    /// <param name="sender"></param>
    private static void TimerClear(object sender)
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncClear));
    }

    /// <summary>
    /// 异步清除过期的在线用户
    /// </summary>
    /// <param name="sender"></param>
    private static void AsyncClear(object sender)
    {
        //当前时间
        DateTime timestamp = DateTime.Now.AddMinutes(0 - _ExpiredMinutes);
        //过期的用户列表
        var expiredUserList =
            (from userEntity in _UserList where userEntity.Value.Timestamp <= timestamp Select userEntity);
        if (expiredUserList != null && expiredUserList.Count() > 0)
        {
            List<long> expiredUserIdentities = expiredUserList.Select(o => o.Key).ToList();
            lock (_UserList)
            {
                foreach (long userId in expiredUserIdentities)
                    _UserList.Remove(userId);
            }
        }
    }
    #endregion

    #region 公共方法
    /// <summary>
    /// 增加在线用户
    /// </summary>
    /// <param name="userIdentity">用户身份标识</param>
    /// <param name="userInfo">用户实体</param>
    public static void Add(long userIdentity, T userInfo)
    {
        lock (_UserList)
        {
            #region 创建用户实体
            UserEntity<T> userEntity = new UserEntity<T>
            {
                Timestamp = DateTime.Now,
                UserInfo = userInfo
            };
            #endregion

            if (_UserList.Keys.Contains(userIdentity))
            {
                _UserList[userIdentity] = userEntity;
            }
            else
            {
                _UserList.Add(userIdentity, userEntity);
            }
        }
    }

    /// <summary>
    /// 
                    

                    
                

服务热线

153 8323 9821

功能和特性

价格和优惠

网站和维护

推广和优化

微信服务号