2014-07-22 14 views
13

Attualmente sto sviluppando un'applicazione utilizzando hub SignalR (2.1).Segnale: rilevamento della connessione attiva nei client C#

Ho 1 client WPF e l'altro è un client WCF. Tutto funziona bene nel senso che stanno trasmettendo perfettamente i messaggi.

L'unico problema che ho affrontato ora è che ho notato che OnDisconnected non è stato affatto attivato quando l'applicazione si spegne per motivi come il riavvio automatico, il server WCF andato giù e pochi altri. Il timeout è il valore predefinito di 30 secondi. Non viene mai chiamato neanche dopo che è trascorso un giorno (ho provato). Tuttavia, il timeout funziona per i client Web.

Funziona solo quando chiamo hub.connection.stop().

Il metodo Ondisconnected tuttavia funziona molto bene quando il client è un browser.

Quindi, vorrei chiedere se esiste un modo per il lato Signal R Hub di essere in grado di verificare se il client è ancora connesso o è già uscito (come un ping)?

+1

1) si dovrebbe presentare un bug su github per il client .net signalr (o forse hanno anche un bug?). 2) puoi facilmente implementare il tuo meccanismo di ping, inviando meccanismi avanti e indietro tra client e hub –

+0

Bene, ho letto e noto questo testo dicendo "Se i tuoi server web smettono di funzionare o l'applicazione si riavvia, il metodo OnDisconnected non viene chiamato Pertanto, è possibile che il repository di dati disponga di record per gli ID di connessione che non sono più validi. " in http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections. Quindi, so che loro lo sanno.Ma, la mia domanda è, c'è qualche modo integrato per il mozzo SignalR di notare se la connessione è stata rilasciata invece di eseguire il ping ogni due secondi. – Kiong

risposta

23

In SignalR 2.1.0, c'è un new overload to OnDisconnected che accetta un bool che indica se il client è disconnesso con garbo o meno. Il ragionamento alla base di questo cambiamento è spiegato nella sezione "Cambiamenti di rottura" di 2.1.0 release notes.

Il nuovo metodo OnDisconnected potrebbe essere simile a questo:

public override Task OnDisconnected(bool stopCalled) 
{ 
    if (stopCalled) 
    { 
     // We know that Stop() was called on the client, 
     // and the connection shut down gracefully. 
    } 
    else 
    { 
     // This server hasn't heard from the client in the last ~35 seconds. 
     // If SignalR is behind a load balancer with scaleout configured, 
     // the client may still be connected to another SignalR server. 
    } 

    return base.OnDisconnected(stopCalled); 
} 

Il vecchio metodo OnDisconnected che non prende un bool non si chiama per disconnette non aggraziati, quindi se si utilizza tale evento, che potrebbe spiegare il problema che stai vedendo.

Prima del 2.1.0, il metodo (solo) OnDisconnected che non ha preso un parametro è stato chiamato per entrambi i nodi di connessione non aggraziati con agevolezza e. Poiché questo cambiamento nel comportamento ha causato several reported issues, il vecchio sovraccarico OnDisconnected is being removed in SignalR's upcoming 2.1.1 release.

In questo modo, le applicazioni che utilizzano il vecchio metodo OnDisconnected di SignalR non riescono a compilare quando sono costruite contro SignalR 2.1.1. Anche se questo non è l'ideale, si spera che gli sviluppatori siano a conoscenza di questo cambiamento sostanziale in modo da avere l'opportunità di modificare le loro app in modo appropriato prima di distribuirle.

+0

Perfetto. Ho appena provato e sì. Questo sta sparando. Grazie mille signore! – Kiong

+0

halter73, grazie. Ho trovato un piccolo errore. Il metodo OnDisconnected non viene attivato se utilizzo "virtuale" nella riga successiva: public virtual Task OnDisconnected (bool stopCalled) Uso "override" invece "virtual" e funziona. –

+0

Grazie. Ho risolto la mia risposta. – halter73

0

Ho riscontrato che il mio client non si ricollega se ho forzato il server a chiudere la connessione. (Mi piacerebbe avere un errore di WSSockets)

Quindi, per me, la correzione è stata:

con = new HubConnection(_url); 
con.Error += (exception) => Error(exception); 
con.Start(); 

poi, nel metodo errore, tentativo di ricollegare richiamando nuovamente il codice di cui sopra.

Problemi correlati