Finalmente l'ho capito. Ecco cosa ho imparato dall'inizio di questa domanda:
Background: stiamo creando un'app iOS usando Xamarin / Monotouch e il client .NET SignalR 2.0.3. Stiamo usando i protocolli SignalR predefiniti e sembra che stia usando SSE invece dei socket web. Non sono ancora sicuro se sia possibile utilizzare i socket Web con Xamarin / Monotouch. Tutto è ospitato utilizzando i siti Web di Azure.
Avevamo bisogno che l'app si riconnettesse rapidamente al nostro server SignalR, ma continuavamo ad avere problemi in cui la connessione non si ricollegava da sola o la riconnessione richiedeva esattamente 30 secondi (a causa di un timeout del protocollo sottostante).
C'erano tre scenari per i quali abbiamo finito per testare:
Scenario A: connessione la prima volta che l'app è stata caricata. Questo ha funzionato perfettamente dal primo giorno. La connessione viene completata in meno di 0,25 secondi anche su connessioni mobili 3G. (supponendo che la radio sia già accesa)
Scenario B: riconnessione al server SignalR dopo che l'app è rimasta inattiva / chiusa per 30 secondi. In questo scenario, il client SignalR alla fine si riconnetterà al server da solo senza alcun lavoro speciale, ma sembra attendere esattamente 30 secondi prima di tentare di riconnettersi. (troppo lento per la nostra app)
Durante questo periodo di attesa di 30 secondi, abbiamo provato a chiamare HubConnection.Start () che non ha avuto alcun effetto. E anche la chiamata a HubConnection.Stop () richiede 30 secondi. Ho trovato un bug correlato sul sito SignalR che sembra essere stato risolto , ma abbiamo ancora lo stesso problema nella v2.0.3.
Scenario C: riconnessione al server SignalR dopo che l'app è rimasta inattiva / chiusa per 120 secondi o più. In questo scenario, il protocollo di trasporto SignalR è già scaduto, quindi il client non si riconnette mai automaticamente. Questo spiega perché il client a volte, ma non sempre, si ricollegava da solo. La buona notizia è che la chiamata a HubConnection.Start () funziona quasi istantaneamente come lo scenario A.
Quindi mi ci è voluto un po 'per rendermi conto che le condizioni di riconnessione erano diverse a seconda che l'app fosse chiusa per 30 secondi rispetto a 120+ secondi. E sebbene i log di traccia di SignalR illuminino cosa sta succedendo con il protocollo sottostante, non credo che ci sia un modo per gestire gli eventi a livello di trasporto nel codice. (l'evento Closed () si attiva dopo 30 secondi nello scenario B, istantaneamente nello scenario C; la proprietà State dice "Connesso" durante questi periodi di attesa di riconnessione; nessun altro evento o metodo rilevante)
Soluzione:
la soluzione è ovvia. Non stiamo aspettando che SignalR esegua la sua magia di riconnessione. Invece, quando l'app viene attivata o quando viene ripristinata la connessione di rete del telefono, stiamo semplicemente ripulendo gli eventi e de-referenziando HubConnection (non possiamo eliminarlo perché ci vogliono 30 secondi, si spera che la garbage collection se ne occuperà ) e creando una nuova istanza. Ora tutto funziona alla grande. Per qualche ragione, ho pensato che dovremmo riutilizzare una connessione persistente e riconnetterci invece di creare solo una nuova istanza.