Laden...

[Gelöst]Event Handler im SignalR Hub

Erstellt von Palin vor 6 Jahren Letzter Beitrag vor 6 Jahren 1.400 Views
P
Palin Themenstarter:in
1.090 Beiträge seit 2011
vor 6 Jahren
[Gelöst]Event Handler im SignalR Hub

Hallo Zusammen,

ich hab aktuell das Problem, das ich eigendlich ein Event in einem SiganlR Hub nutzen möchte. Was aber nicht funktioniere, da für jedem Aufruf ein neuer Hub erzeugt und direkt wieder Disposed wird. Also OnConnected und OnDesconnected werden auf Verschiedenen Instanzen ausgeführt. Hinzu kommt das es zur Kommunikation mit einen an einer Com Schnittstelle angeschlossenen Gerät dienen soll, an das so wohl Befehle Gesendet werden sollen, wie auch Events abgefangen werden sollen, die dann an die SignalR Clients gesendet werden sollen.

Hier mal Vereinfacht der Quellcode:

Die StartUp Klasse


 public class ComHostStartup
    {
        private readonly IComServer> _comServer = new ComServer();

       public void Configuration(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);

            GlobalHost.DependencyResolver.Register(typeof(ComHub), () => new ComHub(_comServer.Value));

            app.MapSignalR();
        }

    }

Und hier der Hub mit einfachen Beispiel Methoden

    public class ComHub : Hub , IDisposable
    {
        private readonly IComServer _comServer;

        public ComHub(IComServer comServer)
        {
            _comServer= comServer;
            _comServer.OnChanged += this.ComServer_Changed;
           //Hier ist das Problem wenn ich im Dispose, das Event nicht entferne bekomme ich ein Memory Leak und da Event wird mehrfach ausgeführt.
          // , da der ComServer dann eine Referenz auf dem Hub hat.
          // wenn ich im Dispose das Event Entferne ist des direkt wider weg, 
         //da das Dispose so fort ausgeführt wird. 
         //Und es gibt keinen Listener mehr der auf die Events Reagiert.
 
        }

        public void Send(string name, string message)
        {
            Clients.All.Send(name, message);
        }

        private void ComServer_OnChanged(object sender, ComChangedEventArgs e)
        {
            Send("ComChanged", e.Daten);
        }

        public void Stop()
        {
            _comServer.Stop();
        }

      protected override void Dispose(bool disposing)
        {
            _comServer.OnChanged -= this.ComServer_OnChanged;
            base.Dispose(disposing);
        }

Aktuell sehe ich die Möglichkeit im StartUp das Event vom Server zu abonnieren und da entweder über den DependencyResolver mir eine Instanz des Hub zu holen und dann dort die Methode aufzurufen (wurde ich aktuell bevorzugen) oder oder im Hub eine Methode bereitzustellen die ich dann über IP, Port usw anspreche.

Vielleicht hat ja schon mal jemand was ähnliche gemacht und hat da eine bessere Lösung oder Erfahrung mit den Lösungen und hat da Tipps welche die bessere ist.

MFG
Palin

Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern

1.029 Beiträge seit 2010
vor 6 Jahren

Hi,

soweit ich das überblicken kann ist deine erste Idee die übliche Vorgehensweise für so ein Problem. Ist ja soweit normal, dass SignalR immer ein neues Hub erstellt.

Quasi also:


private void ComServer_OnChanged(object sender, ComChangedEventArgs e)
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<ComHub>();
        // daten senden
    }

LG

P
Palin Themenstarter:in
1.090 Beiträge seit 2011
vor 6 Jahren

Danke für die Hilfe.

ich hatte es jetzt zuerst über den Dependency Resolver versucht was nicht funktioniert hatte.


var hub = GlobalHost.DependencyResolver.Resolve<ComServerHub>();
hub.Send("Name", "Message");

Mit dem Context hat es dann Funktioniert.


var context = GlobalHost.ConnectionManager.GetHubContext<ActiveRuestplatzHub>();
context.Clients.All.Send("ComChanged", e.Daten);

Das SignalR immer einen neuen Hub erstellt, hatte ich in der Docu überlesen. Ich hab da beim Debuggen gestern ordentlich geflucht. Weil ich mir einen Bakepoint in der OnConnected und OnDisconnected gesetzt. Hab gesehen, das beide Methoden aufgerufen wurden und mich gewundert, das in der OnDiconnetet Methode zwar der Code Ausgeführt wurde um den Event Handler zu entfernen, er aber nicht entfernt wurde. Was ich erst mal gar nicht verstanden habe, bis ich einem Brakepoint im Konstruktor hatte und feststellte, das der deutlich öfter aufgerufen wurde als ich dachte.

Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern