Finalmente me di cuenta de esto. Esto es lo que he aprendido desde que comencé esta pregunta:
Antecedentes: estamos creando una aplicación para iOS con Xamarin / Monotouch y el cliente .NET SignalR 2.0.3. Estamos usando los protocolos SignalR predeterminados, y parece estar usando SSE en lugar de sockets web. Todavía no estoy seguro de si es posible usar sockets web con Xamarin / Monotouch. Todo se aloja mediante sitios web de Azure.
Necesitábamos que la aplicación se reconectara rápidamente a nuestro servidor SignalR, pero seguíamos teniendo problemas en los que la conexión no se reconectaba por sí sola, o la reconexión tardaba exactamente 30 segundos (debido a un tiempo de espera del protocolo subyacente).
Hubo tres escenarios que terminamos probando:
Escenario A: conexión la primera vez que se cargó la aplicación. Esto funcionó a la perfección desde el primer día. La conexión se completa en menos de 0,25 segundos incluso a través de conexiones móviles 3G. (asumiendo que la radio ya está encendida)
Escenario B: volver a conectarse al servidor de SignalR después de que la aplicación estuvo inactiva / cerrada durante 30 segundos. En este escenario, el cliente de SignalR eventualmente se volverá a conectar al servidor por sí solo sin ningún trabajo especial, pero parece esperar exactamente 30 segundos antes de intentar volver a conectarse. (demasiado lento para nuestra aplicación)
Durante este período de espera de 30 segundos, intentamos llamar a HubConnection.Start () que no tuvo ningún efecto. Y llamar a HubConnection.Stop () también lleva 30 segundos. Encontré un error relacionado en el sitio de SignalR que parece estar resuelto , pero seguimos teniendo el mismo problema en la v2.0.3.
Escenario C: volver a conectarse al servidor de SignalR después de que la aplicación estuvo inactiva / cerrada durante 120 segundos o más. En este escenario, el protocolo de transporte de SignalR ya ha agotado el tiempo de espera, por lo que el cliente nunca se vuelve a conectar automáticamente. Esto explica por qué el cliente a veces, pero no siempre, se reconectaba por sí solo. La buena noticia es que llamar a HubConnection.Start () funciona casi instantáneamente como el escenario A.
Así que me tomó un tiempo darme cuenta de que las condiciones de reconexión eran diferentes en función de si la aplicación estaba cerrada durante 30 segundos frente a más de 120 segundos. Y aunque los registros de seguimiento de SignalR iluminan lo que sucede con el protocolo subyacente, no creo que haya una forma de manejar los eventos de nivel de transporte en el código. (el evento Cerrado () se activa después de 30 segundos en el escenario B, instantáneamente en el escenario C; la propiedad del estado dice "Conectado" durante estos períodos de espera de reconexión; ningún otro evento o método relevante)
Solución:
la solución es obvia. No estamos esperando que SignalR haga su magia de reconexión. En cambio, cuando se activa la aplicación o cuando se restablece la conexión de red del teléfono, simplemente estamos limpiando los eventos y eliminando la referencia a HubConnection (no podemos desecharla porque toma 30 segundos, con suerte la recolección de basura se encargará de ello ) y creando una nueva instancia. Ahora todo funciona muy bien. Por alguna razón, pensé que deberíamos reutilizar una conexión persistente y reconectarnos en lugar de simplemente crear una nueva instancia.