可以通過SessionID和用戶名來保證同一個用戶不能同時登錄的問題,下面程序模仿了QQ的登錄,當登錄后判斷當前帳號是否已經登錄,如果登錄。則踢掉以前登錄的用戶。
1.通過Application全局變量來存儲SessionID和用戶名,每次登錄時都保存,並且將該Application存入Hashtable中,當用戶登錄成功后,首先判斷該用戶是否已經存儲在Application中,如果存在(說明已經登錄),則將該用戶對應的值設置為XX(值為無用),
代碼 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->protected void loginbtn_Click(object sender, EventArgs e) { //登錄成功。。。。。。。 Hashtable hOnline = (Hashtable)Application["Online"];//讀取全局變量 if (hOnline != null) { IDictionaryEnumerator idE = hOnline.GetEnumerator(); string strKey = ""; while (idE.MoveNext()) { if (idE.Value != null && idE.Value.ToString().Equals(this.txtName.Text))//如果當前用戶已經登錄, { //already login strKey = idE.Key.ToString(); hOnline[strKey] = "XX";//將當前用戶已經在全局變量中的值設置為XX break; } } } else { hOnline = new Hashtable(); } hOnline[Session.SessionID] = this.txtName.Text;//初始化當前用戶的 Application.Lock(); Application["Online"] = hOnline; Application.UnLock(); Response.Redirect("main.aspx"); }
2,寫一個BasePage加一個Init方法如下,系統的所有頁面均繼承自該BasePage
代碼 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> protected override void OnInit(EventArgs e) { Hashtable hOnline = (Hashtable)Application["Online"];//獲取已經存儲的application值 if(hOnline != null) { IDictionaryEnumerator idE = hOnline.GetEnumerator(); while(idE.MoveNext()) { if(idE.Key != null && idE.Key.ToString().Equals(Session.SessionID)) { //already login if (idE.Value != null && "XX".Equals(idE.Value.ToString()))//說明在別處登錄 { hOnline.Remove(Session.SessionID); Application.Lock(); Application["Online"] = hOnline; Application.UnLock(); Response.Write("<script>alert('你的帳號已在別處登陸,你被強迫下線!');top.location.href='Default.aspx';window.close();</script>");//退出當前到登錄頁面 // Response.Redirect("Default.aspx"); Response.End(); // return false; } //break; } } }
3.在程序退出后從Application中清除當前SessionID
代碼 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->void Session_End(object sender, EventArgs e) { // 在會話結束時運行的代碼。 // 注意: 只有在 Web.config 文件中的 sessionstate 模式設置為 // InProc 時,才會引發 Session_End 事件。如果會話模式設置為 StateServer // 或 SQLServer,則不會引發該事件。 Hashtable hOnline = (Hashtable)Application["Online"]; if (hOnline[Session.SessionID] != null) { hOnline.Remove(Session.SessionID);//清除當前SessionID Application.Lock(); Application["Online"] = hOnline; Application.UnLock(); } }
4.如果程序非正常退出,SessionID沒有及時的清除,那么也不會影響帳號的正常登錄,而SessionID也會隨着Session的過期而自動清除,服務器也不會有壓力。
5,如果感覺存儲在Application中感覺不好,也可以將SessionID存入數據庫中,判斷方法和上面一樣。
6,測試時注意在不同機器上面測試,同一台機子上面的SessionID是一樣的,每次設置為XX后又有新值進去,看不到效果,如果要防止同一個帳號在同一台機子上面同事登錄兩次以上,可以通過mac地址來判斷。
