Я наконец понял это. Вот что я узнал, задав этот вопрос:
Предыстория: мы создаем приложение для iOS с использованием Xamarin / Monotouch и клиента .NET SignalR 2.0.3. Мы используем протоколы SignalR по умолчанию - и, похоже, он использует SSE вместо веб-сокетов. Я еще не уверен, можно ли использовать веб-сокеты с Xamarin / Monotouch. Все размещается на веб-сайтах Azure.
Нам нужно было приложение для быстрого переподключения к нашему серверу SignalR, но у нас продолжали возникать проблемы, когда соединение не восстанавливалось само по себе - или переподключение занимало ровно 30 секунд (из-за тайм-аута базового протокола).
Мы протестировали три сценария:
Сценарий A - подключение при первой загрузке приложения. Это работало безупречно с первого дня. Подключение выполняется менее чем за 0,25 секунды даже при использовании мобильных подключений 3G. (при условии, что радио уже включено)
Сценарий B - повторное подключение к серверу SignalR после того, как приложение было бездействующим / закрыто в течение 30 секунд. В этом сценарии клиент SignalR в конечном итоге повторно подключится к серверу самостоятельно без каких-либо специальных действий, но, похоже, он ждет ровно 30 секунд перед попыткой повторного подключения. (слишком медленно для нашего приложения)
В течение этого 30-секундного периода ожидания мы пытались вызвать HubConnection.Start (), но это не дало результата. И вызов HubConnection.Stop () также занимает 30 секунд. Я обнаружил связанную ошибку на сайте SignalR, которая, похоже, устранена , но у нас все еще есть та же проблема в версии 2.0.3.
Сценарий C - повторное подключение к серверу SignalR после простоя / закрытия приложения в течение 120 секунд или дольше. В этом сценарии для транспортного протокола SignalR уже истекло время ожидания, поэтому клиент никогда не подключается автоматически. Это объясняет, почему клиент иногда, но не всегда, повторно подключался сам. Хорошая новость в том, что вызов HubConnection.Start () работает почти мгновенно, как сценарий A.
Мне потребовалось время, чтобы понять, что условия повторного подключения были разными в зависимости от того, было ли приложение закрыто на 30 секунд или более 120 секунд. И хотя журналы трассировки SignalR освещают то, что происходит с базовым протоколом, я не верю, что есть способ обрабатывать события транспортного уровня в коде. (событие Closed () срабатывает через 30 секунд в сценарии B, мгновенно в сценарии C; в свойстве State указано «Connected» во время этих периодов ожидания повторного подключения; никаких других соответствующих событий или методов)
Решение:
Решение очевидно. Мы не ждем, пока SignalR выполнит свою магию повторного подключения. Вместо этого, когда приложение активируется или когда сетевое соединение телефона восстанавливается, мы просто очищаем события и отменяем ссылку на HubConnection (не можем удалить его, потому что это занимает 30 секунд, мы надеемся, что сборка мусора позаботится об этом. ) и создание нового экземпляра. Теперь все отлично работает. По какой-то причине я подумал, что нам следует повторно использовать постоянное соединение и переподключаться, а не просто создавать новый экземпляр.