62,051
社区成员
发帖
与我相关
我的任务
分享
/// <summary>
/// 用户基础类
/// </summary>
public class OnlineUser
{
#region 私有字段
private string id;
private string name = "游客";
private DateTime startTime = DateTime.Now;
private DateTime lastTime = DateTime.Now;
private string lastIP;
private bool isUser = false;
private string lastUrl;
#endregion
#region 公共属性
/// <summary>
/// 获取或设置用户名
/// </summary>
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
/// <summary>
/// 获取或设置ID
/// </summary>
public string ID
{
get
{
return id;
}
set
{
id = value;
}
}
/// <summary>
/// 获取或设置开始访问时间
/// </summary>
public DateTime StartTime
{
get
{
return startTime;
}
set
{
startTime = value;
}
}
/// <summary>
/// 获取或设置最后访问时间
/// </summary>
public DateTime LastTime
{
get
{
return lastTime;
}
set
{
lastTime = value;
}
}
/// <summary>
/// 获取或设置是否会员(True会员False游客)
/// </summary>
public bool IsUser
{
get
{
return isUser;
}
set
{
isUser = value;
}
}
/// <summary>
/// 获取或设置用户IP
/// </summary>
public string LastIP
{
get
{
return lastIP;
}
set
{
lastIP = value;
}
}
/// <summary>
/// 获取或设置最后请求网址
/// </summary>
public string LastUrl
{
get
{
return lastUrl;
}
set
{
lastUrl = value;
}
}
/// <summary>
/// 获取在线时间(秒)
/// </summary>
public double OnlineSeconds
{
get
{
return (lastTime - startTime).TotalSeconds;
}
}
#endregion
}
#region 私有方法
/// <summary>
/// 重建用户列表排序
/// </summary>
/// <param name="UserNode"></param>
private void ReNewUser(LinkedListNode<OnlineUser> UserNode)
{
if (UserNode.List != null)
{
UserNode.List.Remove(UserNode);
}
_OnlineUserLink.AddFirst(UserNode);
UserNode.Value.LastTime = DateTime.Now;
}
/// <summary>
/// 重建
/// </summary>
/// <param name="UserNode"></param>
/// <param name="U_LastUrl"></param>
private void ReNewUser(LinkedListNode<OnlineUser> UserNode, string U_LastUrl)
{
if (UserNode.List != null)
{
UserNode.List.Remove(UserNode);
}
_OnlineUserLink.AddFirst(UserNode);
UserNode.Value.LastTime = DateTime.Now;
UserNode.Value.LastUrl = U_LastUrl;
}
/// <summary>
/// 清除到期在线用户
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ClearTimeOutUser(object sender, System.Timers.ElapsedEventArgs e)
{
double NextRunTime = timeOut;
DateTime _CheckTime = e.SignalTime.AddMilliseconds(timeOut * -1);
_UpdateTimer.Stop();
try
{
readerWriterLock.AcquireWriterLock(Timeout.Infinite);
if (_OnlineUserLink.Count > 0)
{
LinkedListNode<OnlineUser> UserNode = _OnlineUserLink.Last;
TimeSpan ts = UserNode.Value.LastTime - _CheckTime;
if (ts.TotalMilliseconds <= 0)
{
if (UserNode.Previous != null)
{
ts = UserNode.Previous.Value.LastTime - _CheckTime;
if (ts.TotalMilliseconds <= 0)
NextRunTime = 1;
else
NextRunTime = ts.TotalMilliseconds;
}
Remove(UserNode);
}
else
{
NextRunTime = ts.TotalMilliseconds;
}
}
_UpdateTimer.Interval = NextRunTime;
}
finally
{
readerWriterLock.ReleaseWriterLock();
}
_UpdateTimer.Start();
}
#endregion
}
#region 公共方法
/// <summary>
/// 插入用户
/// </summary>
/// <param name="onlineUser">用户</param>
public void Add(OnlineUser onlineUser)
{
LinkedListNode<OnlineUser> listNode = new LinkedListNode<OnlineUser>(onlineUser);
try
{
readerWriterLock.AcquireWriterLock(Timeout.Infinite);
if (allUserList.ContainsKey(onlineUser.ID))
{
ReNewUser(listNode);
}
else
{
if (onlineUser.IsUser)
{
if (!userList.ContainsKey(onlineUser.ID))
{
userList.Add(onlineUser.ID, listNode);
allUserList.Add(onlineUser.ID, listNode);
ReNewUser(listNode);
}
else
{
ReNewUser(listNode);
}
}
else
{
allUserList.Add(onlineUser.ID, listNode);
ReNewUser(listNode);
}
}
}
finally
{
readerWriterLock.ReleaseWriterLock();
}
}
/// <summary>
/// 更新用户请求信息
/// </summary>
/// <param name="id">id</param>
public void Update(string id)
{
LinkedListNode<OnlineUser> OutNodeUser;
try
{
readerWriterLock.AcquireWriterLock(Timeout.Infinite);
if (allUserList.TryGetValue(id, out OutNodeUser))
{
ReNewUser(OutNodeUser);
}
}
finally
{
readerWriterLock.ReleaseWriterLock();
}
}
/// <summary>
/// 访问请求
/// </summary>
/// <param name="id">id</param>
/// <param name="url">url</param>
public void Update(string id, string url)
{
LinkedListNode<OnlineUser> OutNodeUser;
try
{
readerWriterLock.AcquireWriterLock(Timeout.Infinite);
if (allUserList.TryGetValue(id, out OutNodeUser))
{
ReNewUser(OutNodeUser, url);
}
}
finally
{
readerWriterLock.ReleaseWriterLock();
}
}
/// <summary>
/// 根据id移除用户
/// </summary>
/// <param name="id">id</param>
public void Remove(string id)
{
LinkedListNode<OnlineUser> UserNode;
try
{
readerWriterLock.AcquireWriterLock(Timeout.Infinite);
if (allUserList.TryGetValue(id, out UserNode))
{
Remove(UserNode);
}
}
finally
{
readerWriterLock.ReleaseWriterLock();
}
}
/// <summary>
/// 移除用户资料
/// </summary>
/// <param name="UserNode"></param>
private void Remove(LinkedListNode<OnlineUser> UserNode)
{
if (UserNode.List != null)
{
allUserList.Remove(UserNode.Value.ID);
if (UserNode.Value.IsUser)
userList.Remove(UserNode.Value.ID);
UserNode.List.Remove(UserNode);
}
}
/// <summary>
/// 获取在线用户列表
/// </summary>
public IList<OnlineUser> GetOnlineUsers()
{
readerWriterLock.AcquireReaderLock(Timeout.Infinite);
IList<OnlineUser> lst = new List<OnlineUser>();
foreach (OnlineUser var in _OnlineUserLink)
{
lst.Add(var);
}
readerWriterLock.ReleaseReaderLock();
return lst;
}
/// <summary>
/// 获取用户信息
/// </summary>
/// <param name="name">id</param>
/// <returns></returns>
public OnlineUser GetOnlineUser(string id)
{
OnlineUser value = default(OnlineUser);
LinkedListNode<OnlineUser> NodeUser;
try
{
readerWriterLock.AcquireReaderLock(Timeout.Infinite);
if (userList.TryGetValue(id, out NodeUser))
{
value = NodeUser.Value;
}
}
finally
{
readerWriterLock.ReleaseReaderLock();
}
return value;
}
/// <summary>
/// 根据用户名检测是否在线
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public bool IsOnlineUser(string id)
{
bool rBool = false;
try
{
readerWriterLock.AcquireReaderLock(Timeout.Infinite);
if (userList.ContainsKey(id))
{
rBool = true;
}
}
finally
{
readerWriterLock.ReleaseReaderLock();
}
return rBool;
}
/// <summary>
/// 清除所有在线人数
/// </summary>
public void Clear()
{
readerWriterLock.AcquireWriterLock(Timeout.Infinite);
userList.Clear();
allUserList.Clear();
_OnlineUserLink.Clear();
readerWriterLock.ReleaseWriterLock();
}
#endregion
/// <summary>
/// 用户在线类
/// </summary>
/// <typeparam name="string">Key</typeparam>
/// <typeparam name="OnlineUser">值</typeparam>
public class CacheOnline
{
#region 私有字段
private static CacheOnline instance;
private static readonly object syncRoot = new object();
//会员列表
private Dictionary<string, LinkedListNode<OnlineUser>> userList;
//所有人数列表
private Dictionary<string, LinkedListNode<OnlineUser>> allUserList;
//所有会员列表排序
private LinkedList<OnlineUser> _OnlineUserLink;
/// <summary>
/// Cache锁
/// </summary>
protected ReaderWriterLock readerWriterLock = new ReaderWriterLock();
//定时器
private System.Timers.Timer _UpdateTimer;
//登陆超时时间(毫秒)
private int timeOut=1000 * 60 * 30;
#endregion
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
private CacheOnline()
{
userList = new Dictionary<string, LinkedListNode<OnlineUser>>();
allUserList = new Dictionary<string, LinkedListNode<OnlineUser>>();
_OnlineUserLink = new LinkedList<OnlineUser>();
_UpdateTimer = new System.Timers.Timer();
_UpdateTimer.AutoReset = true;
_UpdateTimer.Elapsed += new System.Timers.ElapsedEventHandler(ClearTimeOutUser);
_UpdateTimer.Interval = timeOut;
_UpdateTimer.Start();
}
#endregion
#region 公共属性
/// <summary>
/// 获取所有用户总数
/// </summary>
public int AllCount
{
get
{
return allUserList.Count;
}
}
/// <summary>
/// 获取会员总数
/// </summary>
public int MemberCount
{
get
{
return userList.Count;
}
}
/// <summary>
/// 获取或设置登陆超时时间(毫秒)
/// </summary>
public int TimeOut
{
get
{
return timeOut;
}
set
{
timeOut=value;
}
}
/// <summary>
/// 获取一个对象实例,该对象在整个运用程序中唯一
/// </summary>
/// <returns></returns>
public static CacheOnline GetInstance()
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new CacheOnline();
}
}
}
return instance;
}
#endregion