Calling SignalR hub clients from elsewhere in system

64,506

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

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

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

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

Solution 5

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;
    }
Share:
64,506
Jordan Wallwork
Author by

Jordan Wallwork

Senior software developer at Tech 13, artificial intelligence and computer science graduate and all round geek. Hoping to do my PhD next year in bristol in advanced computer vision

Updated on July 05, 2022

Comments

  • Jordan Wallwork
    Jordan Wallwork almost 2 years

    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

  • Jordan Wallwork
    Jordan Wallwork over 12 years
    Yeah I'm using the SignalR samples to try and work this out. The dictionaries are static, so the information persists over multiple instances of the class, that's why I'd hoped I could simply create an instance of Hooking.cs and use that, but it doesn't work
  • nmat
    nmat over 12 years
    And don't forget to add using SignalR.Infrastructure;