2013-03-20 11 views
8

Wir stoßen auf ein interessantes Problem. Hier ist, was unser Setup wie folgt aussieht:SignalR .NET-Client trennt

  • SignalR Server (eine ASP.NET MVC-Anwendung) auf Windows Server 2012.
  • Sencha HTML5-Apps (SignalR Clients) auf dem gleichen Server (Windows Server 2012).
  • .NET Windows-Dienst auf einem Windows Server 2008 R2-Server. Dies dient auch als SignalR-Client.
  • Anfangs verwendeten wir SignalR 0.5.3 - als wir anfingen zu beobachten, dass die Verbindung des Windows-Dienstes zum Signal-R-Server ausfällt. Die Häufigkeit hierfür liegt im Bereich von einigen Minuten bis zu einigen Stunden. In den meisten Fällen wird die Verbindung wieder hergestellt, die Verbindung wird jedoch gelegentlich nicht wiederhergestellt, sodass der Windows-Dienst alle paar Tage seine Verbindung verliert. Aber es gibt kein festgelegtes Muster. Es hat nichts mit Serverneustarts/Backups usw. zu tun. Wir fügten dem Windows-Dienst Protokollierung hinzu, um das StateChanged-Ereignis auf der Clientverbindung zu überwachen und stellten fest, dass das Ereignis ausgelöst wird, wenn es die Verbindung trennt und wieder herstellt, aber nicht, wenn es nicht erneut verbindet.

    Dann kamen wir in diesem Thread: client constantly reconnecting

    und beschlossen, alles zu SignalR 1.0.1 (mussten wir tun es trotzdem irgendwann) zu aktualisieren. Der Windows-Dienst wurde auch auf Framework 4.5 (ab Framework 2.0) aktualisiert, das jetzt auf die neue Microsoft.AspNet.SignalR.Client.dll verweist. Dies ermöglichte uns (mithilfe einer neu hinzugefügten Verbindungseigenschaft) festzustellen, dass der Windows-Dienst tatsächlich das ServerSentEvents-Protokoll verwendet hat. Das Installieren des gleichen Windows-Diensts auf einem Windows Server 2012-Computer verwendet das WebSockets-Protokoll. Dies steht im Einklang mit diesem Thema: SignalR .NET Client doesn't support WebSockets on Windows 7

    Das Verhalten des Dienstes auf dem Windows Server 2008 R2-Server hat sich jedoch nicht geändert. Es trennt sich immer noch und verbindet sich erneut und verliert seine Verbindung von Zeit zu Zeit. Aufgrund einiger Einschränkungen können wir den Windows Server 2012 nicht für den Windows-Dienst verwenden und sind mit älteren Betriebssystemen beschäftigt. Das soll nicht heißen, dass Windows-Dienste, die das WebSockets-Protokoll verwenden, all unsere Probleme lösen würden (wir haben das nicht gründlich getestet). Das dritte, was wir ausprobiert haben, ist, den Quellcode von GitHub zu bekommen und ihn zu kompilieren und die Dienste (SignalR Server und die Clients) zu aktualisieren - das wurde gemacht, um sicherzustellen, dass wir die neueste Kopie mit allen möglichen Bugfixes bekommen.

    Aber es hat nicht geholfen. Wir sind jetzt an einem Punkt, an dem wir unsere Möglichkeiten erschöpft zu haben scheinen. Vorschläge würden sehr geschätzt werden. Vielen Dank.

    =====================================

    EDIT: Weitere Informationen :

    Okay, jetzt haben wir weitere Informationen. Wir haben Code in den Windows-Dienst (SignalR Client) hinzugefügt, um sich alle 30 Minuten beim SignalR Server anzumelden (zum Testen der Verbindung).

    Hier ist, was auf der Client-Seite geschieht alle 30 Minuten:

    WriteEvent(Now(), "INFO", "PING", "Performing logon procedure with SiteCode = " & msSiteCode & ".") 
    trans.Invoke("login", New String() {msSiteCode, "", "SERVER", "", ""}) 
    

    wo trans die Instanz der serverseitigen Klasse von Hub zu erben, und Writeevent ist im Grunde eine Spur in eine Protokolldatei zu schreiben .

    und die Client-Seite hat auch eine ‚isLoggedIn‘ Methode wie folgt:

    Private Sub isLoggedIn(ByVal bLoggedIn As String) 
         If bLoggedIn Then 
          WriteEvent(Now(), "INFO", "", "SignalR Server: Authenticated")   
         Else 
          WriteEvent(Now(), "ERROR", "", "SignalR Server: Authentication failed") 
         End If 
    End Sub 
    

    Auf der Serverseite wir die Login-Methode haben:

    Public Sub login(ByVal sAccount As String, _ 
            ByVal sCompanyCode As String, _ 
            ByVal sClientId As String, _ 
            ByVal sPassword As String, _ 
            ByVal sModuleCode As String) 
         Try 
          'Some code omitted that validates the user and sets bValidated. 
    
          If bValidated Then 
           'Update user in cache 
           ConnectionCache.Instance.UpdateCache(userId, Context.ConnectionId, UserCredential.Connection_Status.Connected) 
           Clients.Caller.isLoggedIn(True) 
    
           Dim connectionId As String = ConnectionCache.Instance.FindConnectionId(userId) 
           LogEvent("Successful login for connectionid: " & connectionId & ". Context. User: " & userId, _ 
             EventLogEntryType.Information) 
          Else 
           Clients.Caller.isLoggedIn(False, results) 
          End If 
         Catch ex As Exception 
          LogEvent("Login: " & ex.Message, EventLogEntryType.Error) 
         End Try 
    End Sub 
    

    Wenn wir uns auf der Client-Protokolldatei Alle 30 Minuten erhalten wir die folgenden Protokolleinträge:

    • Durchführen der Anmeldeprozedur mit SiteCode = ABCD.
    • SignalR Server: authentifizierte

    So wissen wir, dass das Login-Server-Side-Verfahren genannt wird, und die isLoggedIn clientseitige Methode auch genannt wird.

    Zu einem bestimmten Zeitpunkt wird die clientseitige Methode isLoggedIn jedoch nicht aufgerufen, während die serverseitige Methode aufgerufen wird. Also alle 30 Minuten beginnen wir nur einen Eintrag zu bekommen:

  • Durchführen der Anmeldeprozedur mit SiteCode = ABCD.

Darüber hinaus ist das Protokollereignis:

LogEvent("Successful login for connectionid: " & connectionId & ". Context. User: " & userId, EventLogEntryType.Information) 

in der serverseitigen Login-Methode wird auf dem serverseitigen Protokoll geschrieben. Also Clients.Caller.isLoggedIn (True) wird wie erwartet aufgerufen, aber wir sehen das nicht auf der Client-Seite.

Also ich denke, was wir suchen ist, dass der Client immer auf den Server zugreifen kann und in der Lage ist, die Server-Seite (Login) -Funktion aufzurufen, aber der Server ruft die Client-Seite (IsLoggedIn) -Funktion, und Das fängt irgendwann an.

Dies könnte auch etwas für .NET-Clients sein, da ich mir ziemlich sicher bin, dass dies bei unseren HTML5/Javascript-Clients nicht passiert ist.

+0

Wenn Sie möchten, können Sie das nächtliche Paket für den Kunden auf diesem Myget Feed www ausprobieren.myget.org/F/aspnetwebstacknightly/. Wir haben jetzt clientseitige Protokollierung (Die Verbindung verfügt über eine TextWriter-Eigenschaft connection.Trace). Sie können dies verwenden, um zu sehen, was passiert und warum sich die Dinge nicht in Ihrem Netzwerk verhalten. – davidfowl

+0

Danke. Wir haben jetzt ein paar weitere Ereignisse protokolliert und die ursprüngliche Frage mit weiteren Informationen aktualisiert. – smitra

+0

Sie benötigen clientseitige Protokollierung, nicht serverseitige Protokollierung. – davidfowl

Antwort

2

Am Ende haben wir nur eine einfache "PINGING" -Funktion erstellt. Dies wird alle 15 Minuten aufgerufen. Die Logik ist wie folgt:

  • SignalR Client verfügt über einen Zeitgeber, der die Server-PING-Methode alle 15 Minuten aufruft.
  • Der Server ruft als Antwort die Clientmethode PINGCLIENT auf dem Client auf.
  • Im nächsten PING-Timer-Ereignis auf dem Client (nach 15 Minuten) überprüfen wir, ob die Antwort erhalten hat. Wenn nicht, unterbrechen wir alle Aktivitäten und initialisieren die Hub-Verbindung erneut. Starten Sie dann den PINGING-Timer neu.
  • Also während wir aufgaben, herauszufinden, was die Ursache war, haben wir eine Problemumgehung, um den Verlust von "Server-zu-Client" -Verbindung zu verwalten, wenn es passiert. Beachten Sie, dass dies zusätzlich zur integrierten Re-Connection-Logik in SignalR gilt.

    Wir führen auch Protokolle und im Durchschnitt passiert das (der Client bekommt kein PING zurück vom Server) vielleicht einmal am Tag.