c#stateserverはマシン間のセッションを維持します
-
10-07-2019 - |
質問
私は、私が見ることができないいくつかの痛みを伴う明白な失態を作ったと確信しています。私はあなたの一人が私をまっすぐに設定できることを望んでいます。
セッション管理は完全に機能しています。ただし、あるマシンのユーザーがデータを入力すると、別のマシンでセッションを開始したユーザーも最初からセッション情報を取得します。あまり良くない。 :(
セッションを次のように呼び出します:
UserInfo userinfo = UserInfo.Session;
私のセッションmgtクラスはこれを使用します:
static UserInfo userInfo;
static public UserInfo Session
{
get
{
if (userInfo == null)
{
userInfo = new UserInfo();
userInfo.ResetSessionTime();
}
return userInfo;
}
}
このようにデータを読み書きします。クラス全体をシリアル化できることはわかっていますが、必要な1つまたは2つのアイテムを取得するのではなく、クラスが呼び出されるたびにクラス全体をシリアル化および逆シリアル化することで、オーバーヘッドが大きくなるようです。
Decimal _latitude;
private String SessionValue(String sKey, String sValue, String sNewValue)
{
String sRetVal = "";
if (sNewValue == null)//not wanting to update anything
{
if (sValue == null)//there is no existing value
{
sRetVal = (String)System.Web.HttpContext.Current.Session[sKey];
}
else
{
sRetVal = sValue;
}
}
else
{
System.Web.HttpContext.Current.Session[sKey] = sNewValue;
sRetVal = sNewValue;
}
return sRetVal;
}
public Decimal Latitude
{
get { return SessionValue("Latitude", _latitude); }
set { _latitude = SessionValue("Latitude", _latitude, value); }
}
ご協力ありがとうございます
解決
1)UserInfoにstaticを使用しているため、このクラスの単一のインスタンスがWebサーバーに送信されるすべてのリクエストで共有されます。
2)セッション(ユーザー間で共有されない)だけでなく、インスタンス変数にも値を保存します。この場合、ユーザー間で共有されます。
したがって、_latitudeの値が原因でこの問題が発生しています。簡単な解決策は次のとおりです。
public class Userinfo
{
public Decimal Latitude
{
get { return System.Web.HttpContext.Current.Session["Latitude"]; }
set { System.Web.HttpContext.Current.Session["Latitude"] = value; }
}
}
より良い、よりテスト可能なバージョンは次のようになります:
public class UserInfo
{
private HttpSessionStateWrapper _session;
public UserInfo(HttpSessionStateWrapper session)
(
// throw if null etc
_session = session;
)
public Decimal Latitude
{
get { return _session["Latitude"]; }
set { _session["Latitude"] = value; }
}
}
2番目のインスタンスでは、リクエスト内で HttpSessionStateWrapper (現在のセッションを使用)をUserInfoインスタンスに渡します。テストするときは、モックラッパーを渡すだけです。
どのような場合でも、UserInfoインスタンスはセッション間で共有されるべきではなく、セッションから直接読み書きする必要があります。セッション値のローカルバージョンを保持することによって、物事を時期尚早に最適化しようとしないでください。時間を節約することはできず、バグにさらされているだけです。
他のヒント
これは、静的フィールドにユーザー情報を保存するために発生します。静的インスタンスはすべてのリクエスト間で共有され、アプリケーションのライフタイム全体で使用されます。
つまり、すべてのユーザーはUserInfo.Sessionから同じUserInfoインスタンスを取得します。
これを修正するには:
- クラス全体をセッションにシリアル化します。他にどのプロパティがあるかはわかりませんが、それほどオーバーヘッドにならないでしょう。
- リクエストごとにUserInfoのインスタンスを作成し、ユーザーが常に新しいインスタンスから読み取るようにします。これにより、セッションからの値が更新されます。