IIS Background thread and SignalR

2019-07-03 00:23发布

问题:

I need to have a background thread that does some work and sends data to the users connected to the service through SignalR.

I thought of hosting this thread inside IIS, and to spawn it when Application_Start is first hit, or in a separate worker process.

If I host it in IIS and create it at the start of the application - The thread starts only when the app is first hit. I need it running as soon as I start the service. - I do not have control over this thread via a desktop GUI, I can't stop or pause it in a simple way.

If I host it in a separate process, such as a Windows Service - I don't have access to the SignalR service instance - I don't want to connect to the SignalR service as a user to send data to other users. I wanr a different approach to this, one that doesn't imply the worker being a client to SignalR itself.

What is your opinnion on this ? Do you see any other solution ?

回答1:

The way we have approached this is to create a separate endpoint on the web application that your Windows service can call.

Imagine the following URI exists in an ASP.NET MVC controller: http://[myserver]/api/TellUsers/[msg]. Inside of this method, you can get the connected hub clients and make the call.

[HttpPut]
public void TellUsers(string msg)
{
   var connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>();
   var demoClients = connectionManager.GetClients<MyHubDerivedClass>();
   demoClients.TellUsers(msg);
}

[Insert caveat about proper error checking here.]

Of course, you don't have to use MVC. Any publicly accessible URI would work. As for securing it, you can use any valid technique for securing ASP.NET endpoints.



回答2:

I know the question is rather old but:

In truth i rather like the "client itself" example you have. This gives you control from many different points rather than just one. Example - multiple services can call over to control the service. I can't see any reason you can't have an admin user which is able to invoke "special" commands that others users can't.

That's a tried and tested design for many systems. I'd stick with it.