原帖:http://community.csdn.net/Expert/topic/3835/3835032.xml?temp=.1909601
感謝:Afritxia (能活不易)
當用戶訪問網站時,會爲他分配一個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();
}