- C# code
/*当用户访问网站时,会为他分配一个SessionID。令用户的IP地址和用户名称建立一个一一对应的关系。如果用户开启了新的窗口,则检查用户的IP地址或用户名是否已经在OnlineUsersHash中出现过?如果出现过,就让新的SessionID指向现有的IP地址。而当一个Session结束时,则将该SessionID从OnlineUsers_SessionIPHash中移除。判断是否还有其他SessionID指向这个IP地址,如果没有,那么从在线用户列表中移除用户名称。客户端的情况相当复杂,必须要考虑周全。下面则是新的算法的代码: */// 在Global.asax.cs 文件中 // // 在线用户列表主键名 public const string KEY_ONLINEUSERS= "OnlineUsers "; // 在线用户列表 Session 表主键名 public const string KEY_ONLINEUSERS_SESSIONIP= "OnlineUsers_SessionIP "; protected void Application_Start(Object sender, EventArgs e) { Application.Lock(); Application[KEY_ONLINEUSERS]=null; Application[KEY_ONLINEUSERS_SESSIONIP]=null; // 目的是将用户的SessionID和IP对应起来 Application.UnLock(); } protected void Session_Start(Object sender, EventArgs e) { Application.Lock(); /* ... */ Hashtable onlineUsersHash=(Hashtable)Application[KEY_ONLINEUSERS]; Hashtable onlineUsersSessionIPHash=(Hashtable)Application[KEY_ONLINEUSERS_SESSIONIP]; if(Visitor.Current.IsGuest) // 如果用户是来宾 { if(onlineUsersHash.ContainsKey(Request.UserHostAddress)) { onlineUsersHash[Request.UserHostAddress]= " "; } else { onlineUsersHash.Add(Request.UserHostAddress, " "); } } else { if(!onlineUsersHash.ContainsKey(Request.UserHostAddress) && !onlineUsersHash.ContainsValue(Visitor.Current.UserName)) { // 如果用户的 IP 地址和用户名称在列表中找不到,则将添加在线用户列表中 onlineUsersHash.Add(Request.UserHostAddress, Request.Cookies[″UserName″].Value); } else if(onlineUsersHash.ContainsValue(Request.Cookies[“UserName”].Value)) { // 如果用户的 Cookie 信息能够找到,则更新(先删除再添加)在线用户的 IP 地址 // // 说明:用户可能刚登陆不久,便因为线路故障,断线并重新拨号 // 而当用户回到网站时,用户的 Cookie 还未过期,但是 IP 地址却发生了改变 string userName=Request.Cookies[″UserName″].Value; foreach(object key in onlineUsersHash.Keys) { if(((string)onlineUsersHash[key]).Equals(userName)) { // 删除用户刚才使用过的 IP 地址 onlineUsersHash.Remove(key); break; } } // 添加在线用户 onlineUsersHash.Add(Request.UserHostAddress, Request.Cookies[″UserName″].Value); } else if(onlineUsersHash.ContainsKey(Request.UserHostAddress)) { // 如果用户的 IP 地址能找到,则更新在线用户的名称 // // 说明:用户登录后,注销并重新登陆。可能是去换个用户名 onlineUsersHash[Request.UserHostAddress]=Request.Cookies[″UserName″].Value; } } // 将用户的 IP 地址和 SessionID 对应起来 if(!onlineUsersSessionIPHash.ContainsKey(Session.SessionID)) onlineUsersSessionIPHash.Add(Session.SessionID, Request.UserHostAddress); Application.UnLock(); } protected void Session_End(Object sender, EventArgs e) { Application.Lock(); if(Application[KEY_ONLINEUSERS]!=null) { Hashtable onlineUsersHash=(Hashtable)Application[KEY_ONLINEUSERS]; Hashtable onlineUsersSessionIPHash=(Hashtable)Application[KEY_ONLINEUSERS_SESSIONIP]; // 获取用户的IP地址 string IP=(string)onlineUsersSessionIPHash[Session.SessionID]; // 移除用户的IP地址 onlineUsersSessionIPHash.Remove(Session.SessionID); // 如果没有一个Session指向这个IP了,则说明这个用户确实已经离开了网站 // 可以删除该用户的用户名称了 if(!onlineUsersSessionIPHash.ContainsValue(IP)) onlineUsersHash.Remove(IP); } Application.UnLock(); }
------解决方案--------------------------------------------------------
Visitor.cs类定义代码
出处
http://read.pudn.com/downloads74/sourcecode/web/267892/chapter2/%E4%BB%A3%E7%A0%81/InterService/Visitor.cs__.htm
- C# code
/* * Visitor.cs @Microsoft Visual Studio.NET 2003 <.NET Framework 1.1> * Kemvin * 05.29/2005 * * 网站浏览者类,主要是对 SESSION 的操作进行封装 * */ using System; using System.Web; namespace RegLogin.InterService { /// <summary> /// Visitor 论坛浏览者类 /// </summary> public sealed class Visitor { // SESSION 键 public const string NICK_NAME="RI3NO5TL__session_NickName"; // 当前浏览者对象 private static Visitor m_current=new Visitor(); #region 类 Visitor 构造器 /// <summary> /// 类 Visitor 默认构造器 /// </summary> private Visitor() { if(HttpContext.Current==null) throw new NullReferenceException("未能获取 HttpContext.Current 对象"); if(HttpContext.Current.Session==null) throw new NullReferenceException("未能获取 HttpContext.Current.Session 对象"); } #endregion /// <summary> /// 获取当前用户对象 /// </summary> public static Visitor Current { get { return m_current; } } /// <summary> /// 从服务器 SESSION 中获取用户名 /// </summary> public string NickName { get { return HttpContext.Current.Session[NICK_NAME] as string; } } /// <summary> /// 当前用户是否为来宾用户 /// </summary> public bool IsGuest { get { return NickName==null; } } /// <summary> /// 获取用户主机的 IP 地址 /// </summary> public string ClientIP { get { return HttpContext.Current.Request.UserHostAddress; } } /// <summary> /// 获取当前用户是否是论坛管理员 /// </summary> public bool IsBoardAdmin { get { return false; } } } }