1

デスクトップ C# アプリケーションがあり、複数のクライアントが SQL サーバーに接続されています。各ユーザーには ID とパスワードがあります。私が望むのは、すでにログインしているユーザーが別のコンピューターからログインできないようにすることです。

ログイン時にデータベース'UserLoggedIn'=trueの Field を更新し、ユーザーが Field Updated をFalseにログアウトすることで実装しました。しかし、この解決策は最適ではありません。システムがクラッシュしたり、コンピューターが予期せずシャットダウンしたりした場合、値はデータベースで 'UserLoggedIn'=True のままになり、このユーザーはシステムに再度ログインできなくなります。

そのための最適な解決策は何ですか?また、既にログインしているユーザーが別のコンピューターからログインできないようにするにはどうすればよいですか?

4

2 に答える 2

4

の代わりにtrue、タイムスタンプをデータベースに保存します。ユーザーがログインしている間は、定期的に更新してください。

彼らがログインするとき、それがあまり新しくない場合は許可します。つまり、過去 (たとえば) 30 秒以内に別の PC からそれらを見た場合は、そのセッションがまだ有効であると見なし、新しいログインを拒否します。

この方法では、他の PC がクラッシュした場合、タイムスタンプは更新されず、最終的に期限切れになります。

更新頻度は、有効期限タイムアウトの約 2 倍にする必要があります。たとえば、セッションの有効期限を 1 分にしたい場合は、タイムスタンプを 30 秒ごとに更新する必要があります。

于 2013-04-15T09:28:38.497 に答える
0

次のクエリを使用して、ユーザーがデータベースへの接続を既に確立しているかどうかを確認することをお勧めします

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

返されたレコード数が 0 より大きい場合は、ユーザーがアプリケーションからデータベースに既に接続していると見なすことができます。

MSDN の接続文字列プロパティを見ると、次の興味深いプロパティが見つかります。これら 2 つのプロパティを既存の接続文字列に追加して、上記のクエリで定義できるフィルターをさらに改善できます。

  • アプリケーション名- アプリケーションの名前、またはアプリケーション名が指定されていない場合は「.Net SqlClient Data Provider」。(=上記の表のプログラム名)

  • ワークステーション ID - SQL Server に接続しているワークステーションの名前。(=上記の表のホスト名)

このソリューションは、クライアント側でのクラッシュに関係なく機能し、状態をテーブルに保存する必要はないと思います。

于 2013-04-15T09:59:24.883 に答える