Sharing ServiceStack ICacheClient with SignalR

I try to share items in the cache between the ServiceStack OOB ICacheClient and the SignalR hub, but when I try to get a user session in the OnDisconnected event, I get the following error:

Only ASP.NET requests available through Singletons are supported.

I have no problem accessing the session in the OnConnected event, so far this is what I did:

public class HubService:Hub { private readonly IUserRepository _userRepository; private readonly ICacheClient _cacheClient; public HubService(IUserRepository userRepository,ICacheClient cacheClient) { _userRepository = userRepository; _cacheClient = cacheClient; } public override System.Threading.Tasks.Task OnConnected() { var session = _cacheClient.SessionAs<AuthUserSession>(); //Some Code, but No error here return base.OnConnected(); } public override System.Threading.Tasks.Task OnDisconnected() { var session = _cacheClient.SessionAs<AuthUserSession>(); return base.OnDisconnected(); } } 

I am using a simple injector and my ICacheClient is registered as singleton:

  Container.RegisterSingle<ICacheClient>(()=>new MemoryCacheClient()); 

The question is, how can I register requests as singlets in SS? What am I missing at the SignalR event?

Edit:

what I tried to use for register requests in SS is that if it is possible to register SS IHttpRequest using a container and set the lifestyle as singleton due to an exception message, it looks like httpContext and IHttprequest are null on the OnDisconnected event

SS code is as follows:

 public static string GetSessionId(IHttpRequest httpReq = null) { if (httpReq == null && HttpContext.Current == null) throw new NotImplementedException(OnlyAspNet); //message httpReq = httpReq ?? HttpContext.Current.Request.ToRequest(); return httpReq.GetSessionId(); } 

what I'm trying to do is save the list of connected users using ICacheClient, and I just want to remove the connection id from the list when the user disconnects.

Edit: looks like according to danludwig post

β€œSignalR has an interesting thing, when the client disconnects from the hub (for example, closing the browser window), it will create a new instance of the Hub class to call OnDisconnected (). When this happens, HttpContext.Current is null. Therefore, if this hub has any "or any dependencies that are registered for each web request, something is likely to go wrong."

the description above fits my situation perfectly

+4
source share
1 answer

I'm not a SingalR specialist, but based on my experience with it and a simple injector, I don’t think you can get into the session (or request or HttpContext, for that matter) during OnDisconnected. This makes sense if you think about it, although - when the client disconnects from the hub, SignalR no longer has access to the session identifier, there is no request, there is no more communication with the client. OnDisconnected basically tells you "here, do something with this ConnectionId because the client to which it belonged has left." The provided user can return, and then you can access the web goodies (session, request, etc., if you are hosted on IIS) during OnReconnected.

I had similar problems getting some simpleinjector dependencies in order to have the correct life expectancy during these three hub connection events. There was 1 dependency that I wanted to register for every HTTP request, and it worked for everything except OnDisconnected. So I had to hide the SI container in order to use HTTP requests when possible, but use a new area of ​​life when dependency was needed during the OnDisconnected event. If you want to read it, I have a post here that describes my impressions. Good luck.

+4
source

Source: https://habr.com/ru/post/1501569/


All Articles