web-dev-qa-db-ja.com

SignalRハブを介してセッション情報にアクセスできません。私のデザインは間違っていますか?

SignalRハブ内の現在のセッションにアクセスできないことを発見しました。

シナリオを簡略化:チャットを書こうとしました。

現在のユーザーの名前はセッション内に保持されました。

SignalRを使用して、すべての新しいメッセージについて(接続のグループ)を更新しました。

ハブを介して現在のユーザーの名前にアクセスできないことがわかります。

いくつかの回避策があると思いますが、それは私の設計の実装が間違っていたのですか?

その目的でSignalRを使用すべきではありませんか?または、このようにSessionを使用しないでください。

19
Letterman

SignalRでSessionを使用しないでください( SignalRがサーバーでセッションを使用しない を参照)。論理接続は、 ユーザー名にマッピングできる接続ID によって識別されます。

根本的な問題は、SessionStateへの アクセスがASP.NETでシリアル化されて 、状態の一貫性が確保されるため、ハブへの各要求が他の要求をブロックすることです。これまでは、 EnableSessionstateをread-only に設定することで、読み取り専用アクセスを制限しました(ただし、Gistがなくなっているため確認できません)。私が説明したロックの問題を防ぐ)は可能でしたが、 これのサポートが削除されましたSignalRチームが同様のステートメントを行った他のさまざまな場所 も参照してください。最後に、公式の ドキュメントHTTPContext.Current.Sessionに関する記述があります。

24
Lars Höppner

クエリ文字列を介してクライアントからサーバーハブに値を送信できます。

$.connection.hub.start()メソッドの前に、次のようなものを追加できます。

クライアントJSコード:

// Replace "some value" with the session value or anything you want
$.connection.hub.qs = { "Name": "some value" };

$.connection.hub.start()...bla bla bla

ハブのサーバー側では、これを任意の方法で使用できます。

string ClientValue= Context.QueryString["Name"].ToString();

私はセッションでテストしませんでしたが、もちろんクライアント側では、あなたはできる限り素晴らしいかもしれません。

11
Luis Villarroel

セッションがまだ認証されておらず、実際のセッションCookie値を使用したため、ユーザー/ IDを使用できない状況にありました。

 [HubName("headerHub")]
 public class HeaderHub : Hub
 {
    static HeaderHub()
    {
        EventManager.CartUpdated += Update;
        EventManager.LoggedOut += Update;
        EventManager.LoggedIn += Update;
    }

    public override Task OnConnected()
    {
        var group = Context.Request.Cookies["ASP.NET_SessionId"].Value;
        Groups.Add(Context.ConnectionId, group);
        return base.OnConnected();
    }

    private static void Update(object sender, SessionEventArgs e)
    {
        var hubContext = GlobalHost.ConnectionManager.GetHubContext<HeaderHub>();
        hubContext.Clients.Group(e.SessionId).onUpdateHeader();
    }
}

私は誰かがこの解決策で何か問題を見つけると確信しています。もしそうなら、私が通知するクライアントのセットにセッションを結び付けることを達成するより良い方法が欲しいので、コメントしてください。

0
Merritt

最善のアプローチの1つは、セッションの代わりにCookieを使用することです。上記のとおり、セッションは使用できません。したがって、ユーザーがシステムにログインするときは、その一意の識別子(ユーザー名など)をcookieに入れます。次に、セッションにアクセスしたい場所でCookieを使用します。そのような...

  public class CustomUserIdProvider : IUserIdProvider
    {
        public string GetUserId(IRequest request)
        {
           return request.Cookies["ODPUserID"].Value;
        }
    }