2019/3/28 11:28:24
在web開(kāi)發時,有(yǒu)的(de)系統要求同一個(gè)用(yòng)戶在同一時間隻能(néng)登錄一次,也(yě)就是如(rú)果一個(gè)用(yòng)戶已經登錄了,在退出之前如(rú)果再次登錄的(de)話(huà)需要報錯。
常見的(de)處理(lǐ)方法是,在用(yòng)戶登錄時,判斷此用(yòng)戶是否已經在Application中存在,如(rú)果存在就報錯,不存在的(de)話(huà)就加到(dào)Application中(Application是所有(yǒu)Session共有(yǒu)的(de),整個(gè)web應用(yòng)程序唯一的(de)一個(gè)對象):
string strUserId = txtUser.Text;
ArrayList list = Application.Get("GLOBAL_USER_LIST") as ArrayList;
if (list == null)
{
list = new ArrayList();
}
for (int i = 0; i < list.Count; i++)
{
if (strUserId == (list[i] as string))
{
//已經登錄了,提示錯誤信息
lblError.Text = "此用(yòng)戶已經登錄";
return;
}
}
list.Add(strUserId);
Application.Add("GLOBAL_USER_LIST", list);
當然這裏使用(yòng)Cache等保存也(yě)可(kě)以。
接下來就是要在用(yòng)戶退出的(de)時候将此用(yòng)戶從Application中去除,我們可(kě)以在Global.asax的(de)Session_End事件(jiàn)中處理(lǐ):
void Session_End(object sender, EventArgs e)
{
// 在會(huì)話(huà)結束時運行(xíng)的(de)代碼。
// 注意: 隻有(yǒu)在 Web.config 文(wén)件(jiàn)中的(de) sessionstate 模式設置爲
// InProc 時,才會(huì)引發 Session_End 事件(jiàn)。如(rú)果會(huì)話(huà)模式設置爲 StateServer
// 或 SQLServer,則不會(huì)引發該事件(jiàn)。
string strUserId = Session["SESSION_USER"] as string;
ArrayList list = Application.Get("GLOBAL_USER_LIST") as ArrayList;
if (strUserId != null && list != null)
{
list.Remove(strUserId);
Application.Add("GLOBAL_USER_LIST", list);
}
}
這些都(dōu)沒有(yǒu)問題,有(yǒu)問題的(de)就是當用(yòng)戶直接點浏覽器(qì)右上(shàng)角的(de)關閉按鈕時就有(yǒu)問題了。因爲直接關閉的(de)話(huà),并不會(huì)立即觸發Session過期事件(jiàn),也(yě)就是關閉浏覽器(qì)後再來登錄就登不進去了。
這裏有(yǒu)兩種處理(lǐ)方式:
1、使用(yòng)Javascript方式
在每一個(gè)頁面中加入一段javascript代碼:
function window.onbeforeunload()
{
if (event.clientX>document.body.clientWidth && event.clientY<0||event.altKey){
window.open("logout.aspx");
}
}
由于onbeforeunload方法在浏覽器(qì)關閉、刷新、頁面調轉等情況下都(dōu)會(huì)被執行(xíng),所以需要判斷是點擊了關閉按鈕或是按下Alt+F4時才執行(xíng)真正的(de)關閉操作。
然後在logout.aspx的(de)Page_Load中寫和(hé)Session_End相(xiàng)同的(de)方法,同時在logout.aspx中加入事件(jiàn):onload="javascript:window.close()"
但(dàn)是這樣還是有(yǒu)問題,javascript在不同的(de)浏覽器(qì)中可(kě)能(néng)有(yǒu)不同的(de)行(xíng)爲,還有(yǒu)就是當通過文(wén)件(jiàn)->關閉時沒有(yǒu)判斷到(dào)。
2、使用(yòng)xmlhttp方法(這種方法測試下來沒有(yǒu)問題)
在每個(gè)頁面中加入如(rú)下的(de)javascript(這些javascript也(yě)可(kě)以寫在共通裏,每個(gè)頁面引入就可(kě)以了)
var x=0;
function myRefresh()
{
var httpRequest = new ActiveXObject("microsoft.xmlhttp");
httpRequest.open("GET", "test.aspx", false);
httpRequest.send(null);
x++;
if(x<60) //60次,也(yě)就是Session真正的(de)過期時間是30分(fēn)鍾
{
setTimeout("myRefresh()",30*1000); //30秒
}
}
myRefresh();
在web.config中設置
test.aspx頁面就是一個(gè)空頁面,隻不過需要在Page_Load中加入:
Response.Expires = -1;
保證不使用(yòng)緩存,每次都(dōu)能(néng)調用(yòng)到(dào)這個(gè)頁面。
原理(lǐ)就是:設置Session的(de)過期時間是一分(fēn)鍾,然後在每個(gè)頁面上(shàng)定時每30秒連接一次測試頁面,保持Session有(yǒu)效,總共連60次,也(yě)就是30分(fēn)鍾。如(rú)果30分(fēn)鍾後用(yòng)戶還沒有(yǒu)操作,Session就會(huì)過期。當然,如(rú)果用(yòng)戶直接關閉浏覽器(qì),那麽一分(fēn)鍾後Session也(yě)會(huì)過期。這樣就可(kě)以滿足要求了。
深圳市南山區南山街(jiē)道南海(hǎi)大(dà)道西(xī)桂廟路(lù)北陽光(guāng)華藝大(dà)廈1棟4F、4G-04
咨詢電話(huà):136 8237 6272
大(dà)客戶咨詢:139 0290 5075
業(yè)務QQ:195006118
技術(shù)QQ:179981967