No access to the Session information through SignalR Hub. Is my design is wrong?
Asked Answered
P

4

24

I've just discovered you can't access the current session within the SignalR Hub.

Simplified my scenario: I've tried to write a chat.

The name of the current user was kept within the Session.

I've used SignalR to update (a group of connections) about every new message.

Now I see that I can't access the name of the current user through the hub.

I guess there might be some workarounds, but is that implement my design was wrong?

Should I've not used SignalR for that purpose? Or should I not use Session in this way?

Perspicacity answered 11/12, 2013 at 15:0 Comment(0)
E
29

You shouldn't use Session with SignalR (see SignalR doesn't use Session on server). You identify logical connections by their connection id which you can map to user names.

The underlying problem is that access to SessionState is serialized in ASP.NET to ensure state consistency, so each request to the hub would block other requests. In the past, limited read-only access (I assume (but can't confirm since the gist is gone) by setting EnableSessionstate to read-only, which prevents the locking problem I described) was possible, but support for this was dropped. Also see various other places where the SignalR team made similar statements. Lastly: there's a statement in the official documentation about HTTPContext.Current.Session.

Estimation answered 11/12, 2013 at 16:37 Comment(5)
But I already have some information within the session, from normal requests. Should I not use session at all ?Perspicacity
No, you shouldn't use it at all with SignalR. You'll need to find another way of sharing the necessary data - either cache it server-side with your user data, pass it into your hub methods or set state on your hub, depending on the nature of the data.Kieger
Thanks!.. Not disrespecting your knowledge, but can you please give some reference to that? I just want to be surePerspicacity
@Perspicacity I added more detail to my answer, as well as a few linksKieger
@LarsHöppner So am I right to assume the 'correct' way to handle this is keeping connectionID's in session?Drobman
P
14

You could send values from client to server hub via Query String.

Before the $.connection.hub.start() method you could add something like this:

Client JS Code:

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

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

On the server side on the Hub you could use this in any method:

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

I did not test with sessions, but of course on client side you could be as awesome as you can.

Plat answered 31/5, 2015 at 7:33 Comment(0)
S
2

I was in a situation where I couldn't use the User/Identity because the session hadn't been authenticated yet so I just used the actual session cookie value.

 [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();
    }
}

I am sure someone will find something wrong with this solution and if so feel free to comment because I would like a better way to accomplish tying a session to a set of clients to notify.

Skimmia answered 16/11, 2015 at 21:44 Comment(2)
I m new to SignalR, I m also in situation where I need to identify SignalR clients based on some custom id where I thought of using ASP.Net session id. I m also interested in knowing if there is any flaw in these design. Will try out this now :)Alannaalano
I tried to do this but I found that the session ID kept on changing for every request. The session ID isn't persisted until the session is accessed (IE data is stored for the user) This answer explains why.Maritime
I
1

One the best approach is to use Cookie instead of session. because as mentioned above , You can not use session . so When user login to your system, put its unique identifier(such as username) in cookie . then work with cookie where ever you want access session . such below...

  public class CustomUserIdProvider : IUserIdProvider
    {
        public string GetUserId(IRequest request)
        {
           return request.Cookies["ODPUserID"].Value;
        }
    }
Illuminate answered 15/1, 2017 at 13:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.