I\'m trying to improve my application which will require calling a hub from C# instead of javascript. The current workflow for adding a task in my app is:
In order to truly call a hub method, as you call it, you have to be connected to it, and call over that connection. By calling something different (your API) you cannot do that kind of call, and therefore you have to resort to the server initiated broadcasting capabilities, which by nature cannot know about what the Caller
is because there's no SignalR's caller.
That said, if your client calling the API (no matter if it's Javascript or C#) is already connected to the hub when performing the call, you can always decorate your call towards the API with the connectionId
of your hub's connection (by query string, by headers, ...). If your API receives that information, it can then simulate the Caller
API with
Clients.Client(connectionId)
and it can do the same for Others
with
Clients.AllExcept(connectionId)
over a IHubContext
instance. Check the official docs.
You can then follow the suggestion from DDan about encapsulating the IHubContext
usage in a convenient centralized way, or even restructure it a bit to make it easily DI-compliant.
I am using the method explained in this answer.
public class NewsFeedHub : Hub
{
private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<NewsFeedHub>();
// Call this from JS: hub.client.send(channel, content)
public void Send(string groupName, string content)
{
Clients.Group(groupName).addMessage(content);
}
// Call this from C#: NewsFeedHub.Static_Send(groupName, content)
public static void Static_Send(string groupName, string content)
{
hubContext.Clients.Group(groupName).addMessage(content);
}
}
The hub defines and uses its hubContext, so you can do:
var newsFeedHub = new NewsFeedHub();
var newsFeedHub.Static_Send("ch1", "HELLO");
Or:
var taskHub = new TaskHub();
var taskHub.InsertTask(task);
If you prefer that, based on your method naming.