72

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

Leniel Maccaferri
  • 94,281
  • 40
  • 348
  • 451
Jordan Wallwork
  • 2,965
  • 1
  • 22
  • 45
  • But maybe you can help me ;) Any idea how to perform your js code in your broadcast message for all other clients, and not the originating caller who issued the message? :) – GONeale Oct 03 '11 at 11:27
  • Unfortunately I don't. I've been handling this client side, sending the client id back with the response, and simply not calling the function if the id's match – Jordan Wallwork Oct 03 '11 at 12:06

5 Answers5

111

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.

Paolo Moretti
  • 47,973
  • 21
  • 95
  • 89
23

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>();
Greg Ennis
  • 13,126
  • 1
  • 64
  • 70
6

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.

Abrar Jahin
  • 11,997
  • 20
  • 91
  • 139
1

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;
    }
Ian Newson
  • 6,045
  • 2
  • 37
  • 58
1

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.

GONeale
  • 25,353
  • 21
  • 101
  • 146
  • 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 – Jordan Wallwork Oct 03 '11 at 12:04