W końcu to rozgryzłem. Oto, czego się nauczyłem, odkąd zacząłem to pytanie:
Tło: tworzymy aplikację dla systemu iOS przy użyciu platformy Xamarin / Monotouch i klienta .NET SignalR 2.0.3. Używamy domyślnych protokołów SignalR - i wydaje się, że używa SSE zamiast gniazd internetowych. Nie jestem jeszcze pewien, czy można używać gniazd internetowych z platformą Xamarin / Monotouch. Wszystko jest hostowane przy użyciu witryn sieci Web platformy Azure.
Potrzebowaliśmy aplikacji do szybkiego ponownego nawiązania połączenia z naszym serwerem sygnalizującym, ale nadal mieliśmy problemy, w których połączenie nie zostało ponownie połączone - lub ponowne połączenie trwało dokładnie 30 sekund (z powodu przekroczenia limitu czasu podstawowego protokołu).
Testowaliśmy trzy scenariusze:
Scenariusz A - łączenie się przy pierwszym załadowaniu aplikacji. To działało bez zarzutu od pierwszego dnia. Połączenie trwa mniej niż 0,25 sekundy, nawet w przypadku połączeń mobilnych 3G. (zakładając, że radio jest już włączone)
Scenariusz B - ponowne łączenie się z serwerem SignalR po tym, jak aplikacja była bezczynna / zamknięta przez 30 sekund. W tym scenariuszu klient sygnalizujący ostatecznie ponownie połączy się z serwerem bez żadnej specjalnej pracy - ale wydaje się czekać dokładnie 30 sekund przed podjęciem próby ponownego połączenia. (zbyt wolno dla naszej aplikacji)
Podczas tego 30-sekundowego okresu oczekiwania próbowaliśmy wywołać HubConnection.Start (), co nie przyniosło żadnego efektu. Wywołanie HubConnection.Stop () również zajmuje 30 sekund. Znalazłem powiązany błąd w witrynie SignalR, który wydaje się być rozwiązany , ale nadal mamy ten sam problem w wersji 2.0.3.
Scenariusz C - ponowne łączenie się z serwerem SignalR po tym, jak aplikacja była bezczynna / zamknięta przez 120 sekund lub dłużej. W tym scenariuszu protokół transportowy SignalR już przekroczył limit czasu, więc klient nigdy nie łączy się automatycznie ponownie. To wyjaśnia, dlaczego klient czasami, ale nie zawsze, łączył się ponownie samodzielnie. Dobra wiadomość jest taka, że wywołanie HubConnection.Start () działa niemal natychmiast, jak w scenariuszu A.
Zajęło mi trochę czasu, zanim zdałem sobie sprawę, że warunki ponownego połączenia były różne w zależności od tego, czy aplikacja była zamknięta na 30 sekund, czy ponad 120 sekund. I chociaż dzienniki śledzenia sygnalizującego ilustrują, co dzieje się z podstawowym protokołem, nie sądzę, aby istniał sposób obsługi zdarzeń na poziomie transportu w kodzie. (zdarzenie Closed () uruchamia się po 30 sekundach w scenariuszu B, natychmiast w scenariuszu C; właściwość State mówi „Połączono” podczas tych okresów oczekiwania na ponowne połączenie; brak innych odpowiednich zdarzeń lub metod)
Rozwiązanie:
Rozwiązanie jest oczywiste. Nie czekamy, aż SignalR wykona swoją magię ponownego połączenia. Zamiast tego, gdy aplikacja jest aktywowana lub gdy połączenie sieciowe telefonu jest przywracane, po prostu czyścimy zdarzenia i usuwamy odwołania do HubConnection (nie można go usunąć, ponieważ zajmuje to 30 sekund, mam nadzieję, że zajmie się tym odśmiecanie) ) i tworzenie nowej instancji. Teraz wszystko działa świetnie. Z jakiegoś powodu pomyślałem, że powinniśmy ponownie użyć trwałego połączenia i połączyć się ponownie, zamiast po prostu tworzyć nową instancję.