2013-04-15 153 views
1

我有一個桌面C#應用程序,幾個客戶端連接到SQL服務器。每個用戶都有一個ID和密碼。我想要什麼是防止已登錄的用戶從另一臺計算機登錄。防止已登錄的用戶登錄C#

我已經在數據庫中「UserLoggedIn」 =真在登錄更新字段來實現它,而當用戶退出字段更新到。但是這種解決方案並不是最佳的,如果系統崩潰或者計算機意外關機,則數據庫中的值將保持爲'UserLoggedIn'= True,並且該用戶永遠不會再次登錄系統。

什麼是最佳解決方案,並防止已登錄的用戶從另一臺計算機登錄?

+1

反轉邏輯並重新登錄會導致現有會話被終止通常會更好。這可以讓用戶自己解決崩潰/關機問題​​。 –

回答

4

而不是true,在數據庫中存儲一個時間戳。請確保您在用戶登錄時定期更新它。

登錄時,如果它不太新,請允許它們。也就是說:如果您在最後(比如說)30秒內從另一臺PC上看過他們,請考慮該會話仍然存在,並拒絕新的登錄。

這樣,如果他們的其他PC崩潰,時間戳不會被更新,並且最終會過期。

更新頻率應該是到期超時的兩倍。例如,如果您希望會話期限爲1分鐘,則應每30秒更新一次時間戳。

+0

或者只是手動處理和/或隔夜清理工作。似乎像一個古老的問題在某種程度上.. – Paul

+0

@Paul - 作者最好使用內置的成員身份能力插入到ASP.NET –

+0

@Rhhound - 這是一個桌面應用程序。 –

0

我建議你檢查是否使用下面的查詢

SELECT loginame as LoginName,program_name 
FROM sys.sysprocesses 
WHERE db_name(dbid)='my_database' and loginame='test_user' 

如果返回的記錄數大於零,那麼你可以假設用戶有用戶已經建立了與數據庫的連接已經從您的應用程序連接到數據庫。

如果您在MSDN中查看connection string屬性,您會發現以下感興趣的屬性。這2個屬性可以被添加到您現有的連接字符串,以進一步提高,可以在查詢中定義上述

  • 應用程序名稱過濾器 - 應用程序的名稱,或「.net SqlClient數據提供」如果沒有提供應用程序名稱。 (=在以上表格程序名)

  • 工作站ID - 連接到SQL Server的工作站的名稱。 (=上表中的主機名)

我相信這個解決方案將不考慮死機的工作,在客戶端,並且不要求您保存在任何表格中的狀態。

+0

這假設您在不使用連接時保持連接處於打開狀態。通過連接池,這可能是爲你完成的,但是... –

+0

['sys.dm_exec_sessions'](http://msdn.microsoft.com/en-us/library/ms176013.aspx)將是更好的選擇現代的發展,但任何一個都要求用戶具有VIEW SERVER STATE權限 –

+0

羅傑,你是對的。 –

相關問題