Eu finalmente descobri isso. Aqui está o que aprendi desde o início desta pergunta:
Histórico: Estamos construindo um aplicativo iOS usando Xamarin / Monotouch e o cliente .NET SignalR 2.0.3. Estamos usando os protocolos SignalR padrão - e parece estar usando SSE em vez de web sockets. Ainda não tenho certeza se é possível usar sockets web com Xamarin / Monotouch. Tudo é hospedado usando sites do Azure.
Precisávamos que o aplicativo se reconectasse ao nosso servidor SignalR rapidamente, mas continuamos tendo problemas onde a conexão não se reconectava por conta própria - ou a reconexão demorava exatamente 30 segundos (devido a um tempo limite de protocolo subjacente).
Acabamos testando três cenários:
Cenário A - conectando na primeira vez que o aplicativo foi carregado. Isso funcionou perfeitamente desde o primeiro dia. A conexão é concluída em menos de 0,25 segundos, mesmo em conexões móveis 3G. (presumindo que o rádio já esteja ligado)
Cenário B - reconectar ao servidor SignalR após o aplicativo ficar inativo / fechado por 30 segundos. Nesse cenário, o cliente SignalR eventualmente se reconectará ao servidor por conta própria sem nenhum trabalho especial - mas parece esperar exatamente 30 segundos antes de tentar se reconectar. (muito lento para nosso aplicativo)
Durante esse período de espera de 30 segundos, tentamos chamar HubConnection.Start () que não teve efeito. E chamar HubConnection.Stop () também leva 30 segundos. Encontrei um bug relacionado no site SignalR que parece estar resolvido , mas ainda estamos tendo o mesmo problema na v2.0.3.
Cenário C - reconectando-se ao servidor SignalR após o aplicativo ficar inativo / fechado por 120 segundos ou mais. Nesse cenário, o protocolo de transporte SignalR já atingiu o tempo limite, portanto o cliente nunca se reconecta automaticamente. Isso explica por que o cliente às vezes, mas nem sempre se reconectava sozinho. A boa notícia é que chamar HubConnection.Start () funciona quase que instantaneamente como o cenário A.
Então, demorei um pouco para perceber que as condições de reconexão eram diferentes com base no fato de o aplicativo ter sido fechado por 30 segundos versus mais de 120 segundos. E embora os logs de rastreamento SignalR iluminem o que está acontecendo com o protocolo subjacente, não acredito que haja uma maneira de lidar com os eventos de nível de transporte no código. (o evento Closed () dispara após 30 segundos no cenário B, instantaneamente no cenário C; a propriedade State diz "Conectado" durante esses períodos de espera de reconexão; nenhum outro evento ou método relevante
Solução:
a solução é óbvia. Não estamos esperando que o SignalR faça sua mágica de reconexão. Em vez disso, quando o aplicativo é ativado ou a conexão de rede do telefone é restaurada, estamos simplesmente limpando os eventos e retirando a referência do HubConnection (não podemos descartá-lo porque leva 30 segundos, espero que a coleta de lixo cuide disso ) e criando uma nova instância. Agora tudo está funcionando muito bem. Por algum motivo, pensei que deveríamos reutilizar uma conexão persistente e reconectar em vez de apenas criar uma nova instância.