Aufrufen von SignalR-Hub-Clients von einer anderen Stelle im System

71

Ich habe einen SignalR-Hub für die Kommunikation zwischen Server und Client eingerichtet. Der serverseitige Code des Hubs wird in einer Klasse namens Hooking.cs gespeichert. Ich möchte in der Lage sein, eine in Hooking.cs definierte Methode aufzurufen, mit der ich Nachrichten von überall in meiner Anwendung an alle verbundenen Clients senden kann. Es scheint, dass für jeden Client / Server-Aufruf eine neue Instanz von Hooking.cs erstellt wird. Ich hatte also gehofft, dass ich so etwas verwenden kann

var hooking = new Hooking();
hooking.Test();

mit der in Hooking.cs definierten Methode Test () wie z

public static void Test() {
    Clients.test()
}

und mit einem clientseitigen Javascript

var hooking = $.connection.hooking;
hooking.test = function() { alert("test worked"); };
$.connection.hub.start()

Leider ist es nicht so einfach, da Clients nicht statisch sind und daher nicht über eine statische Methode zugänglich sind.

Beim Durchsuchen des SignalR-Quellcodes stieß ich auf eine Methode, die vielversprechend aussah. Hubs.Invoke(string hubName, string method, params object[] args)Ich würde also hoffen, dass ich etwas wie verwenden könnte, Hubs.Invoke("Hooking", "Test")aber ich kann es nicht zum Laufen bringen.

Jede Hilfe dabei wäre sehr dankbar

Jordan Wallwork
quelle
Aber vielleicht können Sie mir helfen;) Haben Sie eine Idee, wie Sie Ihren js-Code in Ihrer Broadcast-Nachricht für alle anderen Clients ausführen können, und nicht für den ursprünglichen Anrufer, der die Nachricht ausgegeben hat? :)
GONeale
Leider nicht. Ich habe diese Client-Seite behandelt, die Client-ID mit der Antwort zurückgeschickt und die Funktion einfach nicht aufgerufen, wenn die ID übereinstimmt
Jordan Wallwork

Antworten:

111

Dies ist der richtige Weg für SignalR 2.x:

var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.addMessage(message);

Grundsätzlich können Sie den Abhängigkeitsauflöser für den aktuellen Host verwenden, um die IConnectionManagerSchnittstelle aufzulösen, mit der Sie das Kontextobjekt für einen Hub abrufen können.

Weitere Informationen finden Sie in der offiziellen Dokumentation .

Paolo Moretti
quelle
23

Hub.GetClients ist in Version 0.4.0 verschwunden.

Aus dem Wiki können Sie jetzt verwenden:

IConnectionManager connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>();
dynamic clients = connectionManager.GetClients<MyHub>();
Greg Ennis
quelle
7
Und vergessen Sie nicht hinzuzufügenusing SignalR.Infrastructure;
nmat
6

Sie können einen Hub einfach verwenden, indem Sie diesen 2 Schritten folgen:

  1. Instanziieren durch Abhängigkeitsinjektion wie folgt:

    public class ClassName
    {
        ........
        ........
        private IHubContext _hub;
    
        public BulletinSenderController(IConnectionManager connectionManager)
        {
            _hub = connectionManager.GetHubContext<McpHub>();
            ........
            ........
        }
    
        ............
        ............
    }
    

2.Verwenden Sie das hubObjekt wie folgt:

_hub.Clients.All.onBulletinSent(bulletinToSend);

Mehr finden Sie hier .

Beispielcode finden Sie in diesem Git-Repo .

Abrar Jahin
quelle
1

Werfen Sie einen Blick auf , wie es in getan Chat.csin SignalR.Samples.Hubs.Chatvon https://github.com/SignalR/SignalR .

Ich kann dort sehen, dass statische Dictionary<TKey, TValue>Elemente oben instanziiert werden, daher stelle ich mir vor, dass sie auch dauerhaft beibehalten werden, entweder wobei die ChatKlasse eine persistente Instanz ist (?) Oder das Array irgendwie aktualisiert wird.

Probieren Sie es aus, David Fowler wäre wahrscheinlich der Beste.

GONeale
quelle
Ja, ich benutze die SignalR-Samples, um das herauszufinden. Die Wörterbücher sind statisch, daher bleiben die Informationen über mehrere Instanzen der Klasse erhalten. Deshalb hatte ich gehofft, ich könnte einfach eine Instanz von Hooking.cs erstellen und diese verwenden, aber es funktioniert nicht
Jordan Wallwork
0

Dies hat sich in .NET Core 2 geändert. Jetzt können Sie die Abhängigkeitsinjektion folgendermaßen verwenden:

    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
quelle