Calling SignalR hub clients from elsewhere in syst

2019-01-16 04:17发布

问题:

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 in 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

回答1:

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.



回答2:

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>();


回答3:

You can easily use a hub by following this 2 step-

  1. 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.



回答4:

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.