SignalRハブ内の現在のセッションにアクセスできないことを発見しました。
シナリオを簡略化:チャットを書こうとしました。
現在のユーザーの名前はセッション内に保持されました。
SignalRを使用して、すべての新しいメッセージについて(接続のグループ)を更新しました。
ハブを介して現在のユーザーの名前にアクセスできないことがわかります。
いくつかの回避策があると思いますが、それは私の設計の実装が間違っていたのですか?
その目的でSignalRを使用すべきではありませんか?または、このようにSession
を使用しないでください。
SignalRでSessionを使用しないでください( SignalRがサーバーでセッションを使用しない を参照)。論理接続は、 ユーザー名にマッピングできる接続ID によって識別されます。
根本的な問題は、SessionStateへの アクセスがASP.NETでシリアル化されて 、状態の一貫性が確保されるため、ハブへの各要求が他の要求をブロックすることです。これまでは、 EnableSessionstateをread-only に設定することで、読み取り専用アクセスを制限しました(ただし、Gistがなくなっているため確認できません)。私が説明したロックの問題を防ぐ)は可能でしたが、 これのサポートが削除されました 。 SignalRチームが同様のステートメントを行った他のさまざまな場所 も参照してください。最後に、公式の ドキュメント にHTTPContext.Current.Session
に関する記述があります。
クエリ文字列を介してクライアントからサーバーハブに値を送信できます。
$.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();
私はセッションでテストしませんでしたが、もちろんクライアント側では、あなたはできる限り素晴らしいかもしれません。
セッションがまだ認証されておらず、実際のセッション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();
}
}
私は誰かがこの解決策で何か問題を見つけると確信しています。もしそうなら、私が通知するクライアントのセットにセッションを結び付けることを達成するより良い方法が欲しいので、コメントしてください。
最善のアプローチの1つは、セッションの代わりにCookieを使用することです。上記のとおり、セッションは使用できません。したがって、ユーザーがシステムにログインするときは、その一意の識別子(ユーザー名など)をcookieに入れます。次に、セッションにアクセスしたい場所でCookieを使用します。そのような...
public class CustomUserIdProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
return request.Cookies["ODPUserID"].Value;
}
}