本文主要介绍 基础平台管理系统(FrameWork) 中的用户在线缓存类,本文提到源码可以去http://framework.supesoft.com下载.
在我们一般开发一个web系统时,都会有一个用户在线列表,记录当前在线用户.以及在线时长/当前访问址/用户IP/等一些用户信息.并保证当前系统只能有一个用户登陆在线.如果当前用户已经在线,可让用户选择是否退出已经登陆用户.
现在大多数系统都使用数据库来记录在线用户列表.使用数据库记录在线用户列表不好之处,用户每次刷新页面都需要更新数据库.增加数据库压力.
在线用户列表 在 基础平台管理系统(FrameWork) 中是通过一个泛型缓存类来实现. 当然了,用数据库有用数据库的好处,用缓存也有用缓存的好处.看各人所需了.
在 基础平台管理系统(FrameWork) 设计用户在线列表主要实现思路:
1.使用缓存记录用户在线列表,在线列表中保存每个在线用户:用户名,进入时间,最后访问时间,登入IP,最后访问地址等.
2.定义一个用户在线时长.如:5分钟,也就是说如果此用户在5分钟没有访问网站页面则将其算为离开.
3.用户登陆流程:
4.用户登入成功后,每访问一个页面.即按用户名,更新一下在线表中的最后访问时间,和最后访问网页地址.
5.使用定时器清除超过5分钟没有更新过的在线列表缓存中的用户.
基础平台管理系统(FrameWork) 在线用户列表泛型缓存类图:
附源码:
缓存源码
/**//************************************************************************************
* Copyright (C) 2007 supesoft.com,All Rights Reserved *
* File: *
* CacheOnline.cs *
* Description: *
* 用户在线类 *
* Author: *
* Lzppcc *
* Lzppcc@hotmail.com *
* http://www.supesoft.com *
* Finish DateTime: *
* 2007年8月6日 *
* History: *
***********************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace FrameWork
{
/**//// <summary>
/// 用户在线类
/// </summary>
/// <typeparam name="TKey">Key</typeparam>
/// <typeparam name="TValue">值</typeparam>
public class CacheOnline<TKey, TValue>
where TKey : IComparable<TKey>
where TValue : OnlineUser<TKey>, new()
{
//会员列表
Dictionary<string, LinkedListNode<TValue>> _MemberUserList;
//所人数列表
Dictionary<TKey, LinkedListNode<TValue>> _AllUserList;
//所有会员列表排序
LinkedList<TValue> _TValueLink;
/**//// <summary>
/// Cache锁
/// </summary>
protected ReaderWriterLock _CacheDataRwl = new ReaderWriterLock();
//定时器
System.Timers.Timer _UpdateTimer;
//用户登陆超时设置(毫秒)
double _TimeOutMilliseconds;
/**//// <summary>
/// 构造函数
/// </summary>
/// <param name="LoginTimeOutMinute">用户登陆超时设置(分钟)</param>
public CacheOnline(int LoginTimeOutMinute)
{
_MemberUserList = new Dictionary<string, LinkedListNode<TValue>>();
_AllUserList = new Dictionary<TKey, LinkedListNode<TValue>>();
_TValueLink = new LinkedList<TValue>();
_TimeOutMilliseconds = 1000 * 60 * LoginTimeOutMinute;
_UpdateTimer = new System.Timers.Timer();
_UpdateTimer.AutoReset = true;
_UpdateTimer.Elapsed += new System.Timers.ElapsedEventHandler(ClearTimeOutUser);
_UpdateTimer.Interval = _TimeOutMilliseconds;
_UpdateTimer.Start();
}
/**//// <summary>
/// 构造函数
/// </summary>
public CacheOnline() : this(30) { }
/**//// <summary>
/// 清除到期在线用户
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ClearTimeOutUser(object sender, System.Timers.ElapsedEventArgs e)
{
double NextRunTime = _TimeOutMilliseconds;
DateTime _CheckTime = e.SignalTime.AddMilliseconds(_TimeOutMilliseconds * -1);
_UpdateTimer.Stop();
try
{
_CacheDataRwl.AcquireWriterLock(Timeout.Infinite);
if (_TValueLink.Count > 0)
{
LinkedListNode<TValue> UserNode = _TValueLink.Last;
TimeSpan ts = UserNode.Value.U_LastTime - _CheckTime;
if (ts.TotalMilliseconds <= 0)
{
if (UserNode.Previous != null)
{
ts = UserNode.Previous.Value.U_LastTime - _CheckTime;
if (ts.TotalMilliseconds <= 0)
NextRunTime = 1;
else
NextRunTime = ts.TotalMilliseconds;
}
Remove(UserNode);
}
else
{
NextRunTime = ts.TotalMilliseconds;
}
}
_UpdateTimer.Interval = NextRunTime;
}
finally
{
_CacheDataRwl.ReleaseWriterLock();
}
_UpdateTimer.Start();
}
/**//// <summary>
/// 获取所有用户列表(IEnumerable)
/// </summary>
public IEnumerable<TValue> GetListIEnumerable
{
get
{
_CacheDataRwl.AcquireReaderLock(Timeout.Infinite);
foreach (TValue var in _TValueLink)
{
yield return var;
}
_CacheDataRwl.ReleaseReaderLock();
}
}
/**//// <summary>
/// 获取在线用户列表(List)
/// </summary>
public List<TValue> GetList
{
get
{
_CacheDataRwl.AcquireReaderLock(Timeout.Infinite);
List<TValue> lst = new List<TValue>();
foreach (TValue var in _TValueLink)
{
lst.Add(var);
}
_CacheDataRwl.ReleaseReaderLock();
return lst;
}
}
/**//// <summary>
/// 获取用户信息
/// </summary>
/// <param name="U_Name"></param>
/// <returns></returns>
public TValue GetValue(string U_Name)
{
TValue value = default(TValue);
LinkedListNode<TValue> NodeUser;
try
{
_CacheDataRwl.AcquireReaderLock(Timeout.Infinite);
if (_MemberUserList.TryGetValue(U_Name, out NodeUser))
{
value = NodeUser.Value;
}
}
finally
{
_CacheDataRwl.ReleaseReaderLock();
}
return value;
}
"插入用户"#region "插入用户"
/**//// <summary>
/// 插入游客
/// </summary>
/// <param name="key"></param>
public void InsertUser(TKey key)
/**//************************************************************************************
* Copyright (C) 2007 supesoft.com,All Rights Reserved *
* File: *
* CacheOnline.cs *
* Description: *
* 用户在线类 *
* Author: *
* Lzppcc *
* Lzppcc@hotmail.com *
* http://www.supesoft.com *
* Finish DateTime: *
* 2007年8月6日 *
* History: *
***********************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace FrameWork
{
/**//// <summary>
/// 用户在线类
/// </summary>
/// <typeparam name="TKey">Key</typeparam>
/// <typeparam name="TValue">值</typeparam>
public class CacheOnline<TKey, TValue>
where TKey : IComparable<TKey>
where TValue : OnlineUser<TKey>, new()
{
//会员列表
Dictionary<string, LinkedListNode<TValue>> _MemberUserList;
//所人数列表
Dictionary<TKey, LinkedListNode<TValue>> _AllUserList;
//所有会员列表排序
LinkedList<TValue> _TValueLink;
/**//// <summary>
/// Cache锁
/// </summary>
protected ReaderWriterLock _CacheDataRwl = new ReaderWriterLock();
//定时器
System.Timers.Timer _UpdateTimer;
//用户登陆超时设置(毫秒)
double _TimeOutMilliseconds;
/**//// <summary>
/// 构造函数
/// </summary>
/// <param name="LoginTimeOutMinute">用户登陆超时设置(分钟)</param>
public CacheOnline(int LoginTimeOutMinute)
{
_MemberUserList = new Dictionary<string, LinkedListNode<TValue>>();
_AllUserList = new Dictionary<TKey, LinkedListNode<TValue>>();
_TValueLink = new LinkedList<TValue>();
_TimeOutMilliseconds = 1000 * 60 * LoginTimeOutMinute;
_UpdateTimer = new System.Timers.Timer();
_UpdateTimer.AutoReset = true;
_UpdateTimer.Elapsed += new System.Timers.ElapsedEventHandler(ClearTimeOutUser);
_UpdateTimer.Interval = _TimeOutMilliseconds;
_UpdateTimer.Start();
}
/**//// <summary>
/// 构造函数
/// </summary>
public CacheOnline() : this(30) { }
/**//// <summary>
/// 清除到期在线用户
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ClearTimeOutUser(object sender, System.Timers.ElapsedEventArgs e)
{
double NextRunTime = _TimeOutMilliseconds;
DateTime _CheckTime = e.SignalTime.AddMilliseconds(_TimeOutMilliseconds * -1);
_UpdateTimer.Stop();
try
{
_CacheDataRwl.AcquireWriterLock(Timeout.Infinite);
if (_TValueLink.Count > 0)
{
LinkedListNode<TValue> UserNode = _TValueLink.Last;
TimeSpan ts = UserNode.Value.U_LastTime - _CheckTime;
if (ts.TotalMilliseconds <= 0)
{
if (UserNode.Previous != null)
{
ts = UserNode.Previous.Value.U_LastTime - _CheckTime;
if (ts.TotalMilliseconds <= 0)
NextRunTime = 1;
else
NextRunTime = ts.TotalMilliseconds;
}
Remove(UserNode);
}
else
{
NextRunTime = ts.TotalMilliseconds;
}
}
_UpdateTimer.Interval = NextRunTime;
}
finally
{
_CacheDataRwl.ReleaseWriterLock();
}
_UpdateTimer.Start();
}
/**//// <summary>
/// 获取所有用户列表(IEnumerable)
/// </summary>
public IEnumerable<TValue> GetListIEnumerable
{
get
{
_CacheDataRwl.AcquireReaderLock(Timeout.Infinite);
foreach (TValue var in _TValueLink)
{
yield return var;
}
_CacheDataRwl.ReleaseReaderLock();
}
}
/**//// <summary>
/// 获取在线用户列表(List)
/// </summary>
public List<TValue> GetList
{
get
{
_CacheDataRwl.AcquireReaderLock(Timeout.Infinite);
List<TValue> lst = new List<TValue>();
foreach (TValue var in _TValueLink)
{
lst.Add(var);
}
_CacheDataRwl.ReleaseReaderLock();
return lst;
}
}
/**//// <summary>
/// 获取用户信息
/// </summary>
/// <param name="U_Name"></param>
/// <returns></returns>
public TValue GetValue(string U_Name)
{
TValue value = default(TValue);
LinkedListNode<TValue> NodeUser;
try
{
_CacheDataRwl.AcquireReaderLock(Timeout.Infinite);
if (_MemberUserList.TryGetValue(U_Name, out NodeUser))
{
value = NodeUser.Value;
}
}
finally
{
_CacheDataRwl.ReleaseReaderLock();
}
return value;
}
"插入用户"#region "插入用户"
/**//// <summary>
/// 插入游客
/// </summary>
/// <param name="key"></param>
public void InsertUser(TKey key)