2015-09-09 6 views
6

Ich verwende derzeit SignalR, um zwischen einem Server und mehreren separaten Prozessen zu kommunizieren, die vom Server selbst erzeugt werden. Beide Server & Client sind in C# codiert. Ich benutze SignalR 2.2.0.0 Auf der Serverseite benutze ich OWIN, um den Server zu betreiben. Ich verwende LightInject auch als IoC-Container.SignalR-Server -> Client-Anruf funktioniert nicht

Hier ist mein Code:

public class AgentManagementStartup 
{ 
    public void ConfigurationOwin(IAppBuilder app, IAgentManagerDataStore dataStore) 
    { 
     var serializer = new JsonSerializer 
     { 
      PreserveReferencesHandling = PreserveReferencesHandling.Objects, 
      TypeNameHandling = TypeNameHandling.Auto, 
      TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple 
     }; 

     var container = new ServiceContainer(); 
     container.RegisterInstance(dataStore); 
     container.RegisterInstance(serializer); 
     container.Register<EventHub>(); 
     container.Register<ManagementHub>(); 
     var config = container.EnableSignalR(); 

     app.MapSignalR("", config); 
    } 
} 

Auf der Client-Seite, melde ich mich auf diese Weise:

public async Task Connect() 
{ 
    try 
    { 
     m_hubConnection = new HubConnection(m_serverUrl, false); 
     m_hubConnection.Closed += OnConnectionClosed; 
     m_hubConnection.TraceLevel = TraceLevels.All; 
     m_hubConnection.TraceWriter = Console.Out; 

     var serializer = m_hubConnection.JsonSerializer; 
     serializer.TypeNameHandling = TypeNameHandling.Auto; 
     serializer.PreserveReferencesHandling = PreserveReferencesHandling.Objects; 

     m_managementHubProxy = m_hubConnection.CreateHubProxy(AgentConstants.ManagementHub.Name); 
     m_managementHubProxy.On("closeRequested", CloseRequestedCallback); 

     await m_hubConnection.Start(); 
    } 
    catch (Exception e) 
    { 
     m_logger.Error("Exception encountered in Connect method", e); 
    } 
} 

Auf der Serverseite I eine enge Anfrage folgendermaßen senden:

var managementHub = GlobalHost.ConnectionManager.GetHubContext<ManagementHub>(); 
managementHub.Clients.All.closeRequested(); 

Ich bekomme nie einen Rückruf in CloseRequestedCallback. Weder auf der Clientseite noch auf der Serverseite bekomme ich Fehler in den Protokollen.

Was habe ich hier falsch gemacht?

EDIT 09/10/15

Nach einigen Recherchen und Modifikationen, fand ich es wurde mit dem Austausch des Behälters IoC verknüpft werden. Als ich alles entfernt habe, was mit LightInject verbunden war und SignalR benutzt habe, hat alles funktioniert. Ich war seit LightInject documented their integration mit SignalR überrascht.

Nachdem ich das gefunden hatte, erkannte ich, dass die GlobalHost.DependencyResolver nicht die gleiche war wie die, die ich an die HubConfiguration lieferte. Sobald ich

hinzugefügt
GlobalHost.DependencyResolver = config.Resolver; 

vor

app.MapSignalR("", config); 

ich jetzt erhalte Rückrufe innerhalb CloseRequestedCallback. Leider bekomme ich folgende Fehler, sobald ich eine Methode vom Client zum Server aufrufen:

Microsoft.AspNet.SignalR.Client.Infrastructure.SlowCallbackException

Mögliche Deadlock erkannt. Ein bei "HubProxy.On" oder "Connection.Received" registrierter Rückruf wurde mindestens 10 Sekunden lang ausgeführt.

Ich bin mir nicht sicher über die Fehlerbehebung, die ich gefunden habe und welche Auswirkungen es auf das System haben könnte. Ist es in Ordnung, die GlobalHost.DependencyResolver durch meine eigene zu ersetzen, ohne alle Standardinhalte zu registrieren?

EDIT 2 09/10/15

Nach this, die GlobalHost.DependencyResolver Veränderung ist das Richtige zu tun. Immer noch ohne Erklärung für die SlowCallbackException, da ich (noch) nichts in meinen Callbacks mache.

+0

In Bezug auf Ihren langsamen Rückruf, vielleicht müssen Sie diesen langsamen Prozess [im Hintergrund] (http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx) ausführen, und einfach SignalR verwenden, um die Aufgabe zu starten ? Wie auch immer, das ist ein separates Problem. Verschieben Sie Ihre IoC-Lösung aus Ihrer Frage und machen Sie eine Antwort. Dann erstellen Sie bei Bedarf eine neue Frage für Ihren langsamen Rückruf. – mason

+0

@ Mason: Ich habe keine lange laufenden Prozess innerhalb eines meiner Rückrufe (Client & Server-Seite). Deshalb bin ich überrascht, diesen Fehler zu bekommen. Ich verstehe Ihren Standpunkt darin, die Frage im selben Thema zu behandeln, aber das Thema scheint verwandt zu sein. – KOTIX

Antwort

3

Ausgabe 1: IoC Container + Dependency Injection

Wenn Sie möchten, für Sie das IOK ändern HubConfiguration, müssen Sie auch die eine vom GlobalHost so ändern, dass der gleichen Hub zurückgibt, wenn es ouside fordern Kontext.

Ausgabe 2: Unerwarteter SlowCallbackException

Diese Ausnahme wurde durch die Tatsache, dass ich mit SignalR innerhalb einer Konsolenanwendung. Der Einstiegspunkt der App nicht async Methode sein kann, um der Lage sein, meine anfängliche Konfiguration aufrufen asynchron I wie folgt tat:

private static int Main() 
{ 
    var t = InitAsync(); 
    t.Wait(); 
    return t.Result; 
} 

für mich Leider verursacht dies eine Menge von Fragen wie here & mehr in Einzelheiten beschrieben here.

Mit dem Start meiner InitAsync wie folgt:

private static int Main() 
{ 
    Task.Factory.StartNew(async()=> await InitAsync()); 
    m_waitInitCompletedRequest.WaitOne(TimeSpan.FromSeconds(30)); 
    return (int)EndpointErrorCode.Ended; 
} 

Alles läuft jetzt gut und ich bekomme keine Deadlocks.

Für weitere Details zu den Problemen & Antworten können Sie auch auf die Änderungen in meiner Frage verweisen.

Verwandte Themen