2013-07-27 7 views
15

Ich benutze SignalR 2 und ich kann nicht herausfinden, wie ich meine Hub-Methoden verwenden kann, z. B. aus einer Controller-Aktion.Hub-Methoden vom Controller verwenden?

Ich weiß, ich kann folgendes tun:

var hub = GlobalHost.ConnectionManager.GetHubContext<T>(); 
hub.Clients.All.clientSideMethod(param); 

Aber das führt das Verfahren direkt auf der Client-Seite.

Was passiert, wenn ich eine Geschäftslogik innerhalb meiner Server-Seite habe? ClientSideMethod(param) Methode Ich möchte von meinem Controller auf die gleiche Weise wie von der Client-Seite aufgerufen werden?

Im Moment verwende ich public static void ClientSideMethod(param) in meinem Hub und in dieser Methode verwende ich die IHubContext aus der ConnectionManager.

Gibt es keine bessere Möglichkeit, dies zu tun?

Die folgende funktioniert nicht (mehr in SignalR 2?):

var hubManager = new DefaultHubManager(GlobalHost.DependencyResolver); 
instance = hubManager.ResolveHub(typeof(T).Name) as T; 
instance.ClientSideMethod(param); 

Es bekomme ich einen "Hub erstellt nicht über Hub-Pipeline nicht unterstützt" Ausnahme, wenn die Clients zugreifen.

+0

Warum tun Sie es nicht aus dem Client, die ich davon ausgehen, JS, können Sie eine Ajax-Anfrage tun und tun, was Sie auf dem Controller – MEYWD

+1

@MEYWD benötigen: Zum Beispiel habe ich eine Admin-Oberfläche, die ich aktualisieren möchte, wenn "etwas passiert". Z.B. Der Client besucht eine bestimmte Seite. Daher möchte ich die Hub-Methode in der Controller-Aktion von dieser Seite aus auslösen. Der eigentliche Kunde kümmert sich nicht darum, warum sollte er diese Nachricht posten? – ChrFin

+0

Ich habe etwas ähnliches getan, ich habe Kunden und Admins (spezielle Client), der Admin einen Befehl senden und wartet auf die Antwort vom Client, um zu tun, dass ich eine Liste von Admins und eine Liste von Clients auf dem Hub, die admin wählt einen Client aus, reserviert ihn, so dass kein anderer Administrator ihn verwendet, sendet dann einen Befehl, der Hub gibt ihn an den Client weiter, der Client gibt die Antwort an den Hub zurück, der im Gegenzug an den Administrator weitergeleitet wird und auf den die Antwort gedruckt wird der Bildschirm – MEYWD

Antwort

11

Als ich eine „gute Lösung“ Ich fand nicht i

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; 
     } 
    } 
} 

Und dann: bin mit Lösung des @ michael.rp mit einigen Verbesserungen:

ich die folgende Basisklasse erstellt haben n der tatsächliche Hub (z.B. public class AdminHub : Hub<AdminHub>) Ich habe (statisch) Methoden wie folgt aus:

/// <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(); 
} 
11

Es Macht Arbeit eine „Helfer“ Klasse zu erstellen, die Ihre Geschäftsregeln implementiert und wird sowohl durch den Hub und den Controller genannt:

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); 
    } 
} 
+0

+1 als es ist schon ein besserer Ansatz als meins, aber ich möchte immer noch eine Möglichkeit, die Hub-Methoden "direkt" zu verwenden, wie es mir "klarer" und "einfacher zu verstehen" scheint ... – ChrFin

+0

@ChrFin Haben Sie jemals einen Weg gefunden, die Hub-Methoden innerhalb der Baugruppe erfolgreich aufzurufen? Ohne in der Lage zu sein, eine Instanz des Hubs aufzurufen, scheint diese Option am DRY zu sein und sich zu unterteilen. –

+0

@BrandonWittwer: Nein, nicht wirklich. Ich habe die Antwort einfach nicht als akzeptiert markiert, da ich immer noch auf eine "native Lösung" hoffe. Ich werde eine Antwort mit meiner Lösung hinzufügen, die ich im Moment habe ... – ChrFin