No Access to the Session Information Through Signalr Hub. Is My Design Is Wrong

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

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.

How to pass data to Signalr hub class

You can't use session in Signalr hub class, see this link

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

There are some solutions to your problem. You can use Standard ASP.NET security to store your global information.

You can store the data you want using this code

FormsAuthentication.SetAuthCookie("string contain your data", false);

and you can retrieve your data using this code

string GlobalData = Context.User.Identity.Name;

SignalR doesn't use Session on server

SignalR connections (including the connection underlying all Hub operations for a client) do not support Session state. You could enable it if you wanted to but we'd strongly recommend against it as session state access serializes requests for a given client, meaning you won't really get the benefit from SignalR duplex messaging anymore, as one request will block the other e.g. in the long polling transport, the receiving connection will block any attempt to send.

Safe way to send session based data to SignalR Hub

I just posted a gist on how to use readonly sessions with SignalR. https://gist.github.com/4692934

Provide user information from signalr request in business logic layer using autofac

Session is not supported by SignalR by default and you should avoid using it. See No access to the Session information through SignalR Hub. Is my design is wrong?. But you still can use cookie or querystring to get the desired value.

In both case you need to have access to the HubCallerContext of the underlying hub, the one that is accessible through the Context property of the Hub.

In a ideal word you should just have to had the dependency to the SignalAuthorizationProvider

ie :

public class SignalrAuthorizationProvider {

public SignalrAuthorizationProvider(HubCallerContext context){
this._context = context;
}

private readonly HubCallerContext _context;

public long? GetUserId() {
return this._context.Request.QueryString["UserId"]
}
}

But due to SignalR design it is not possible. Context property is assigned after construction of the Hub and AFAIK there is no way to change it.

enter image description here

Source code here : HubDispatcher.cs

One possible solution would be to inject a mutable dependency inside the Hub and alter the object in the OnConnected, OnReconnected methods.

public class SignalrAuthorizationProvider : IAuthorizationProvider
{
private Boolean _isInitialized;
private String _userId;
public String UserId
{
get
{
if (!_isInitialized)
{
throw new Exception("SignalR hack not initialized");
}
return this._userId;
}
}

public void OnConnected(HubCallerContext context)
{
this.Initialize(context);
}
public void OnReconnected(HubCallerContext context)
{
this.Initialize(context);
}

private void Initialize(HubCallerContext context) {
this._userId = context.QueryString["UserId"];
this._isInitialized = true;
}
}

and the Hub

public abstract class CustomHub : Hub
{
public CustomHub(IAuthorizationProvider authorizationProvider)
{
this._authorizationProvider = authorizationProvider;
}

private readonly IAuthorizationProvider _authorizationProvider;

public override Task OnConnected()
{
this._authorizationProvider.OnConnected(this.Context);

return base.OnConnected();
}

public override Task OnReconnected()
{
this._authorizationProvider.OnReconnected(this.Context);
return base.OnReconnected();
}
}

Having a mutable dependency is not the best design but I can't see any other way to have access to IRequest or HubCallerContext.

Instead of having an abstract Hub class which is not a perfect solution. You can change the RegisterHubs autofac method to use AOP with Castle.Core and let the interceptor calls the methods for you.



Related Topics



Leave a reply



Submit