Calling SignalR hub clients from elsewhere in system
I've set up a SignalR hub to communicate between the server and client. The hub server side code is stored in a class called Hooking.cs. What I want is to be able to call a method defined in Hooking.cs to allow me to broadcast messages to any connected clients from anywhere in my application. It seems that a new instance of Hooking.cs is created for every client/server call, so I had hoped that I would be able to use something like
var hooking = new Hooking();
hooking.Test();
with the method Test() defined i开发者_如何学Gon Hooking.cs such as
public static void Test() {
Clients.test()
}
and with a the client side javascript
var hooking = $.connection.hooking;
hooking.test = function() { alert("test worked"); };
$.connection.hub.start()
Unfortunately it isn't that simple, as Clients is not static, so not accessible from a static method.
Looking through the SignalR source code I came across a method that looked promising, Hubs.Invoke(string hubName, string method, params object[] args)
, so I would hope I could use something such as Hubs.Invoke("Hooking", "Test")
but I can't make it work.
Any help with this would be hugely appreciated
This is the correct way for SignalR 2.x:
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.addMessage(message);
Basically, you can use the dependency resolver for the current host to resolve the IConnectionManager
interface which allows you to get ahold of the context object for a hub.
Further information can be found in the official documentation.
Hub.GetClients has disappeared in version 0.4.0.
From the wiki you can now use:
IConnectionManager connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>();
dynamic clients = connectionManager.GetClients<MyHub>();
You can easily use a hub by following this 2 step-
Instantiating by dependency injection like this-
public class ClassName { ........ ........ private IHubContext _hub; public BulletinSenderController(IConnectionManager connectionManager) { _hub = connectionManager.GetHubContext<McpHub>(); ........ ........ } ............ ............ }
2.Using the hub
object like this-
_hub.Clients.All.onBulletinSent(bulletinToSend);
More can be found here.
Example code can be found in this git repo.
Have a look at how it's done in Chat.cs
in SignalR.Samples.Hubs.Chat
from https://github.com/SignalR/SignalR.
I can see in there that static Dictionary<TKey, TValue>
's are being instantiated at the top, so I imagine they are being maintained persistently too, either with the Chat
class being a persisted instance (?) or that array being updated somehow.
Check it out, David Fowler would probably be the best on this.
This has changed in .NET Core 2, now you can use dependency injection like this:
private readonly IHubContext<MyHub,IMyHubInterface> _hubContext;
public MyController(MyHub,IMyHubInterface hubContext)
{
_hubContext = hubContext;
}
public bool SendViaSignalR()
{
_hubContext.Clients.All.MyClientSideSignalRMethod(new MyModel());
return true;
}
精彩评论