Use Hub methods from controller?
It might work to create a "helper" class that implements your business rules and is called by both your Hub and your Controller:
public class MyHub : Hub{ public void DoSomething() { var helper = new HubHelper(this); helper.DoStuff("hub stuff"); }}public class MyController : Controller{ public ActionResult Something() { var hub = GlobalHost.ConnectionManager.GetHubContext<MyHub>(); var helper = new HubHelper(hub); helper.DoStuff("controller stuff"); }}public class HubHelper{ private IHubConnectionContext hub; public HubHelper(IHubConnectionContext hub) { this.hub = hub; } public DoStuff(string param) { //business rules ... hub.Clients.All.clientSideMethod(param); }}
As I did not find a "good solution" I am using @michael.rp's solution with some improvements:
I did create the following base class:
public abstract class Hub<T> : Hub where T : Hub{ private static IHubContext hubContext; /// <summary>Gets the hub context.</summary> /// <value>The hub context.</value> public static IHubContext HubContext { get { if (hubContext == null) hubContext = GlobalHost.ConnectionManager.GetHubContext<T>(); return hubContext; } }}
And then in the actual Hub (e.g. public class AdminHub : Hub<AdminHub>
) I have (static) methods like the following:
/// <summary>Tells the clients that some item has changed.</summary>public async Task ItemHasChangedFromClient(){ await ItemHasChangedAsync().ConfigureAwait(false);}/// <summary>Tells the clients that some item has changed.</summary>public static async Task ItemHasChangedAsync(){ // my custom logic await HubContext.Clients.All.itemHasChanged();}