2013-03-20 21 views
8

Stiamo riscontrando un problema interessante. Ecco ciò che la nostra messa a punto assomiglia:Client SignalR .NET che si disconnette

  • SignalR Server (un'applicazione ASP.NET MVC) in Windows Server 2012.
  • applicazioni HTML5 Sencha (client SignalR) sullo stesso server (Windows Server 2012).
  • Servizio Windows .NET su un server Windows Server 2008 R2. Questo funge anche da client SignalR.

Inizialmente stavamo usando SignalR 0.5.3 - quando abbiamo iniziato a osservare che la connessione del servizio Windows al server R del segnale si interrompe. La frequenza di questo varia da ogni pochi minuti a ogni poche ore. Si ricollega nella maggior parte dei casi, ma non riesce a riconnettersi occasionalmente, il che comporta che il servizio Windows perde la connessione una volta ogni due giorni. Ma non esiste un modello predefinito. Non è collegato al riavvio/backup dei server, ecc. Abbiamo aggiunto la registrazione al servizio Windows per monitorare l'evento StateChanged sulla connessione client e scoperto che l'evento viene generato quando si disconnette e riconnette, ma non quando non si riconnette.

Poi siamo capitati in questa discussione: client constantly reconnecting

e ha deciso di aggiornare tutto per SignalR 1.0.1 (abbiamo dovuto farlo comunque ad un certo punto). Anche il servizio Windows è stato aggiornato al framework 4.5 (dal Framework 2.0) facendo ora riferimento al nuovo Microsoft.AspNet.SignalR.Client.dll. Ciò ci ha consentito anche (utilizzando una proprietà di connessione appena aggiunta) per determinare che il servizio Windows utilizzava effettivamente il protocollo ServerSentEvents. L'installazione dello stesso servizio Windows su una macchina Windows Server 2012 utilizza il protocollo WebSockets. Questo è in linea con questo thread: SignalR .NET Client doesn't support WebSockets on Windows 7

Tuttavia, il comportamento del servizio sul server Windows Server 2008 R2 non è stato modificato. Si disconnette e si riconnette ancora e perde la sua connessione di tanto in tanto. A causa di alcune limitazioni, non possiamo utilizzare Windows Server 2012 per il servizio Windows e siamo bloccati con sistemi operativi meno recenti. Questo non vuol dire che il servizio Windows che utilizza il protocollo websockets risolverebbe tutti i nostri problemi (non l'abbiamo testato a fondo).

La terza cosa che abbiamo provato è ottenere il codice sorgente da GitHub e compilarlo e aggiornare i servizi (SignalR Server e i client) - questo è stato fatto per garantire che otteniamo l'ultima copia con eventuali correzioni di bug.

Ma non ha aiutato. Siamo ora in un punto in cui sentiamo di aver esaurito le nostre opzioni. I suggerimenti sarebbero molto apprezzati. Grazie.

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

EDIT: Informazioni :

Ok, ora abbiamo qualche altra informazione. Abbiamo aggiunto del codice al servizio Windows (SignalR Client) per accedere al SignalR Server ogni 30 minuti (per testare la connessione).

Ecco ciò che accade sul lato client ogni 30 minuti:

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

dove trans è l'istanza della classe sul lato server che eredita da Hub e WriteEvent è fondamentalmente una traccia di scrivere in un file di log .

e il lato client ha anche un metodo 'isLoggedIn' come segue:

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 

Sul lato server abbiamo il metodo login:

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 

Se guardiamo il file di registro del client ogni 30 minuti riceviamo le seguenti voci di registro:

  • Esecuzione della procedura di accesso con SiteCode = ABCD.
  • SignalR Server: autenticato

così sappiamo che il metodo lato server di login viene chiamato, e il metodo lato client isLoggedIn è anche chiamato.

Tuttavia, ad un certo punto, mentre viene chiamato il metodo sul lato server, il metodo lato client isLoggedIn non viene chiamato. Quindi ogni 30 minuti, iniziamo a ottenere una sola voce:

  • Esecuzione della procedura di accesso con SiteCode = ABCD.

Inoltre, l'evento di registro:

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

nel metodo di accesso lato server ottiene scritto sul log lato server. Quindi Clients.Caller.isLoggedIn (True) viene chiamato come previsto, ma non lo vediamo sul lato client.

Quindi immagino che quello che stiamo vedendo è che il client è sempre in grado di accedere al server ed è in grado di chiamare la funzione lato server (login), ma il server fallisce chiamando la funzione lato client (isLoggedIn), e questo inizia ad accadere ad un certo punto.

Inoltre, questo potrebbe essere qualcosa di specifico per i client .NET, in quanto sono abbastanza sicuro che non abbiamo visto questo accada con i nostri client HTML5/javascript.

+0

Se lo desideri, puoi provare il pacchetto notturno per il cliente su questo feed myget www.myget.org/F/aspnetwebstacknightly/. Ora abbiamo la registrazione lato client (La connessione ha una connessione di proprietà TextWriter.Trace). Puoi usare questo per vedere cosa sta succedendo e perché le cose non si stanno comportando sulla tua rete. – davidfowl

+0

Grazie. Ora abbiamo registrato alcuni altri eventi e abbiamo aggiornato la domanda originale con ulteriori informazioni. – smitra

+0

È necessaria la registrazione lato client non la registrazione lato server. – davidfowl

risposta

2

Alla fine, abbiamo appena creato una semplice funzione "PING". Questo viene chiamato ogni 15 minuti. La logica è la seguente:

  1. SignalR Client ha un timer che chiama il metodo PING server ogni 15 minuti.
  2. Il server chiama il metodo PINGCLIENT del client sul client in risposta.
  3. Nel prossimo evento del timer PING sul client (dopo 15 minuti) controlliamo la risposta. In caso contrario, sospenderemo tutte le attività e inizializzeremo nuovamente la connessione Hub. Quindi riavviare il timer PING.

Così, mentre abbiamo rinunciato a cercare di capire quale fosse la causa, abbiamo una soluzione alternativa per gestire la perdita della connessione "da server a client" quando accade. Si noti che questo è in aggiunta alla logica di riconnessione in-built in signalR.

Manteniamo anche i registri e in media ciò accade (il client non riceve un ping dal server) forse una volta al giorno.

Problemi correlati