2011-05-02 51 views
1

我的應用程序我不希望同一用戶名同時登錄,所以我有和想法但我不確定它是否正確。在asp.net中控制用戶的在線狀態

1)當用戶登錄,更新狀態(在數據庫用戶表中的「isOnLine」欄),並保存其登錄時間在會議上,是這樣的:

裏面的登錄方法:

DateTime ltime=Datetime.now(); 

Dbservice.executeSql(update User set(isOnLine,lastLoginTime) value("1",ltime)); 

Session["logintime"]=ltime; 

當另一個用戶嘗試登錄時,檢查該表以查看該用戶的狀態是否被登錄。如果是,請將「isOnline」設置爲「0」,然後他可以立即登錄。

2)在每一個受保護的頁面的Page_Onload()方法,檢查是否在會話中的登錄時間是等於分貝時間:

string logtime=Dbservice.executeSelect("select lastLoginTime from user where xxxxx").Rows[0]["lastLoginTime"]; 

if(!Session["logintime"]==logtime){ 

    //this user should offline now,redirect it to the login page 

} 

我不知道如果我的方式正確與否?

此外,我必須在每個受保護頁面的Page_onLoad方法中編寫檢查邏輯,所以有太多重複代碼,有什麼想法可以避免這種情況?

由於我們網站的所有頁面都受到保護!

謝謝。

UPDATE:

它不是在同一時間讓兩個用戶在線,但允許具有正確pasword可以前者用戶下線強制用戶以後。例如:

user1以「username = bill」登錄並且 「password = 000」,那麼他現在在線。

然後user2的嘗試 「用戶名=法案」和 「密碼= 123」登錄,因爲他的密碼是 無效,所以他的請求被拒絕。

用戶3嘗試 「用戶名=法案」和 「密碼= 000」登錄,因爲他的密碼是 有效的,所以他可以選擇做 用戶1脫機。

在這種情況下,當後來的用戶登錄成功時,但前一個用戶的會話也存在,因此我必須根據會話中的「logintime」檢查它是否在線。

回答

1

如果您不打算使用web farm(或web garden)場景,那麼您可以使用內存結構來跟蹤登錄的用戶。例如,字典類型的靜態全局變量(以線程安全的方式訪問)。

對於通用穩健的解決方案,您需要將此信息保存在數據庫中(如您所示)。我還沒有理解根據會話檢查登錄時間的目的。如需正確解決,請致電

  1. 您需要一個數據庫表來跟蹤用戶的會話。重要字段將被最後訪問時間和活動/非活動狀態。
  2. 在登錄時,如果在db中存在同一用戶的活動會話,則用戶無法登錄
  3. 在特定超時後標記會話處於非活動狀態的作業。這個超時必須比Web服務器會話超時稍大(比如說x分鐘)。
  4. 定期刷新應用程序代碼以重置db中最後訪問的值,以便作業不會將會話標記爲非活動狀態。
  5. 由於db超時= web服務器超時+ x,因此您可以將刷新分爲x分鐘,從而減少數據庫行程。例如,假設x = 3分鐘,則3分鐘內的所有請求都不會修改數據庫中上次訪問的時間(通過減少數據庫訪問次數)。您可以跟蹤會話狀態中的上次數據庫更新時間,並在每個請求中檢查該值,以查看數據庫是否需要更新(即當前時間>上次數據庫更新+ x,然後更新數據庫中最後訪問的值)。

第三步(作業)是可選的,因爲您可以在#2中修改您的檢查以查看登錄嘗試是否在上次訪問時間的n分鐘(其中n>會話超時)之後。

+0

@VinayC:這是我的錯,我更新了我的問題。請檢查::) – hguser 2011-05-02 09:16:18

+0

@hguser,如果僅在成功登錄後纔在數據庫中創建條目,則不需要檢查。 – VinayC 2011-05-02 09:45:35

+0

但是在步驟「在登錄時,如果在db中存在同一用戶的活動會話,則用戶無法登錄」,這取決於如果他的密碼正確,他可以強制登錄的用戶脫機。 – hguser 2011-05-02 12:50:15

0

對於檢查用戶是否已在線的邏輯,我可能想將其放入Global.asax Application_AcquireRequestState事件中,因爲所有頁面都受到保護。

+0

是否有現場示例? – hguser 2011-05-02 08:14:56