SignalR request pipeline, Hub lifetime - signalr

I am starting on signalR with asp.net webapi, and I am trying to understand the whole signalR request/connection pipeline and what is the lifetime of the hub and who creates and dispose the hub instance (does it gets created on every communication between client and server?)
One of the reason is that we need to understand how we should be using an IoC contain in signalR request scenario, how we control the lifetime of the dependency correct specifically the ISession or DBContext.

Hubs instances are created at every single request from a client. They are not kept around, therefore you should not put any state in them.
Hubs are created through a factory system which you can customize through its built-in dependency injection mechanism.

Related

addScoped service lifetime in an ASP.NET Core multithreaded application

I know that AddSingleton() creates a single instance of the service when it is first requested and reuses that same instance in all the places where that service is needed.
If my ASP.NET Core application is multi-threaded, does that mean all HTTP requests from all users will share the same object instance created by dependency injection (DI)?
If so, that would be not a good way if the application process data to be stored. Are there any best practices?
As mentioned in Microsoft documentation, Service lifetimes, it depends on your specific case.
Presumably, if you have a service, A, and you want to create a new instance on every single request, you can use AddScoped() rather than AddSingleton(). A scoped lifetime service would be created per client request.
If for example, it was some shared data that possibly doesn't change between requests such as some values that are computed at application startup and reused throughout the lifetime of the application, then that is a usable scenario.

SignalR Hub Issue - Restarting iis creates a new hub instance

I am using asp.Net SignalR Dependency injection technique for our implementation, so in our case, we have a hub constructor with one parameter. I was wondering if there is a problem I have with the following, or is this how the system should react?
When I restart IIS, signalR will lose connection of course, and then come back online. Afterwards, when it reconnects to our SignalR hub, it attempts to connect to the parameterless Hub constructor instead of the constructor with one parameter that is setup via the NinjectDependecnyResolver. It seems to be trying to connect to the default Hub DependcyResolver after I restart IIS and signalR reconnects. If I refresh the page after the IIS refresh, however, the paramaterized constructor is called, as it should be.
Does anyone know why my provided constructor is not fired after reconnecting to the SignalR hub after an IIS restart/IIS Stop-Start?

What's the lifetime of an object using SignalR with Unity Dependency Resolver?

Let me start with a little setup info... I am using the repository pattern and dependency injection via Unity. The repository is implemented via Linq-To-Sql. I inject my repositories into class constructors in my web project. The repositories have a PerWebRequest lifetime.
I have implemented a few SignalR hubs and have setup a Unity dependency resolver for SignalR. I'm injecting the same repositories into the hubs using the same Unity config file, which specifies these repositories are PerWebRequest also.
Now the punchline... I ran into a problem where the web project would update an Linq-To-Sql entity and the SignalR hub would read that entity and not get the updates. I have "solved" this problem by clearing the Linq-To-Sql cache before reading the entity in the SignalR hub; DataContact.Refresh() didn't update the entire object graph.
My DataContext for these repositories used in hubs are also PerWebRequest but it seams that the SignalR hubs are using a separate DataContext that does not get destroyed after the web request completes. It appears they are acting as singleton instances instead.
Do SignalR apps run in their own process and therefore my DataContext access from the hubs is a separate DataContext in that separate process?
How could the DataContext in the SignalR hub be instantiated with a PerWebRequest lifetime if it a separate process, apart from the web request lifecycle? Also, how does it seemingly act like a Singleton?
It's a while I don't use stuff like Linq2Sql or concepts like PerWebRequest, so I'm not 100% sure, but if I'm correct in saying that PerWebRequest is definitely tied to the lifetime of underlying HTTP requests, then those will hardly work with SignalR because its behavior can change a lot according to the chosen transport strategy. With WebSockets you might have several hub instantiations/method calls over the same connection, while with Long Polling you would probably have one (or zero) per HTTP request. Check here and here.
Given that the code you write with SignalR should be the same regardless of the transport, I think for hubs you'd always have to handle repositories in a specific way, maybe with an ad-hoc factory always clearing the cache each time a repository has to be supplied to a SignalR hub (you could try to be smart and check the transport strategy used, but those could be muddy waters).

Getting specific hub instance associated with a specific SignalRConnectionId

Getting a reference to the client using the SignalRConnectionId is pretty simple via the GlobalHost class. Is there a way to get a reference to a hub instance associated with that client/connection? In other words, given the client connection Guid, can I get a reference to a hub instance that's talking to that client? The reason I want to do this is so I can invoke an instance method on the hub from somewhere else in the server.
It is not possible to get a Hub instance from outside of the SignalR Hub pipeline or the Hub itself.
Hubs are ephemeral in SignalR. Generally a new Hub is instantiated for each invocation, and then disposed immediately after.
This means that a single WebSocket connection can have an arbitrary number of associated Hub instances over its lifetime. Moreover, unless there is an ongoing invocation, it's unlikely that there is even an associated Hub in existence.
I would suggest replicating the Hub instance method you want to call with a static method that takes an IHubContext as a parameter. You can get the IHubContext using GlobalHost.ConnectionManager.GetHubContext.

ASP.NET WebService call queuing

I have an ASP.NET Webform which currently calls a Java WebService. The ASP.NET Webform is created/maintained inhouse, whereas the Java WS is a package solution where we only have a WS interface to the application.
The problem is, that the Java WS is sometimes slow to respond due to system load etc. and there is nothing I can do about this. So currently at the moment there is a long delay on the ASP.NET Webform sometimes if the Java-WS is slow to respond, sometimes causing ASP.NET to reach its timeout value and throw the connection.
I need to ensure data connectivity between these two applications, which I can do by increasing the timeout value, but I cannot have the ASP.NET form wait longer than a couple of seconds.
This is where the idea of a queuing system comes into place.
My idea is, to have the ASP.NET form build the soap request and then queue it in a local queue, where then a Daemon runs and fires off the requests at the Java-WS.
Before I start building something from scratch I need a couple of pointers.
Is my solution viable ?
Are there any libraries etc already out there that I can achieve this functionality with ?
Is there a better way of achieving what i am looking for ?
You can create a WindowsService hosting a WCF service.
Your web app can them call the WCF methods of your Windows Service.
Your windows service can call the java web service methods asynchronously, using the
begin/End pattern
Your windows service can even store the answers of the java web service, and expose them through another WCF methods. For example you could have this methods in your WCF service:
1) a method that allows to call inderectly a java web service and returnd an identifier for this call
2) another method that returns the java web service call result by presenting the identifier of the call
You can even use AJAX to call the WCF methods of your Windows Service.
You have two separate problems:
Your web form needs to learn to send a request to a service and later poll to get the results of that service. You can do this by writing a simple intermediate service (in WCF, please) which would have two operations: one to call the Java service asynchronously, and the other to find out whether the async call has completed, and return the results if it has.
You may need to persistently queue up requests to the Java service. The easiest way to do this, if performance isn't a top concern (and it seems not to be), is to break the intermediate service in #1 into two: one half calls the other half using a WCF MSMQ binding. This will transparently use MSMQ as a transport, causing queued requests to stay in the queue until they are pulled out by the second half. The second half would be written as a Windows service so that it comes up on system boot and starts emptying the queue.
you could use MSMQ for queuing up the requests from you client.
Bear in mind that MSMQ doesn't handle anything for you - it's just a transport.
All it does is take MSMQ messages and deliver them to MSMQ queues.
The creation of the original messages and the processing of the delivered messages is all handled in your own code on the sending and receiving machines: the destination machine would have to have MSMQ installed plus a custom service running to pick them up and process them
Anyway there is a librays for interop with MSQM using JAVA : http://msmqjava.codeplex.com/
Another way could be you can create a queue on one of your windows box and then create a service that pick up the messages form the Queue and foreward them to the Java service

Resources