Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?

like image 588
Letterman Avatar asked Dec 11 '13 15:12

Letterman


People also ask

How do I reconnect my SignalR?

Handle the disconnected event to display a message when an attempt to reconnect has timed out. In this scenario, the only way to re-establish a connection with the server again is to restart the SignalR connection by calling the Start method, which will create a new connection ID.

How do I check if my SignalR is reconnecting?

To test reconnect after the server goes down use iisreset. To simulate client connection dropping (good luck) pull the network cable :) Pulling the network cable won't accurately simulate a client connection dropping when you're using Azure SignalR Service.


4 Answers

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.

like image 134
Lars Höppner Avatar answered Oct 11 '22 06:10

Lars Höppner


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.

like image 27
Luis Villarroel Avatar answered Oct 11 '22 06:10

Luis Villarroel


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.

like image 45
Merritt Avatar answered Oct 11 '22 05:10

Merritt


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;
        }
    }
like image 33
S.Mohamed Mahdi Ahmadian zadeh Avatar answered Oct 11 '22 05:10

S.Mohamed Mahdi Ahmadian zadeh