我终于想通了。这是我从开始这个问题以来学到的东西:
背景:我们正在使用 Xamarin / Monotouch 和 .NET SignalR 2.0.3 客户端构建一个 iOS 应用程序。我们正在使用默认的 SignalR 协议 - 它似乎使用 SSE 而不是 Web 套接字。我还不确定是否可以将 Web 套接字与 Xamarin / Monotouch 一起使用。一切都使用 Azure 网站托管。
我们需要该应用程序快速重新连接到我们的 SignalR 服务器,但我们一直遇到连接没有自行重新连接的问题 - 或者重新连接需要 30 秒(由于底层协议超时)。
我们最终测试了三种场景:
场景 A - 首次加载应用程序时连接。这从第一天开始就完美无缺。即使通过 3G 移动连接,连接也可以在 0.25 秒内完成。(假设收音机已经打开)
场景 B - 在应用程序空闲/关闭 30 秒后重新连接到 SignalR 服务器。在这种情况下,SignalR 客户端最终将自行重新连接到服务器而无需任何特殊工作 - 但它似乎在尝试重新连接之前等待正好 30 秒。(对于我们的应用来说太慢了)
在这 30 秒的等待期间,我们尝试调用 HubConnection.Start(),但没有任何效果。调用 HubConnection.Stop() 也需要 30 秒。我在 SignalR 网站上发现了一个似乎已解决的相关错误,但我们在 v2.0.3 中仍然遇到同样的问题。
方案 C - 在应用程序空闲/关闭 120 秒或更长时间后重新连接到 SignalR 服务器。在这种情况下,SignalR 传输协议已经超时,因此客户端永远不会自动重新连接。这解释了为什么客户端有时但并不总是自行重新连接。好消息是,调用 HubConnection.Start() 几乎可以像场景 A 一样立即工作。
所以我花了一段时间才意识到重新连接的条件是不同的,这取决于应用程序是否关闭了 30 秒和 120 多秒。尽管 SignalR 跟踪日志说明了底层协议的情况,但我不相信有一种方法可以处理代码中的传输级别事件。(在场景 B 中,Closed() 事件在 30 秒后触发,在场景 C 中立即触发;在这些重新连接等待期间,State 属性显示“已连接”;没有其他相关事件或方法)
解决方案:
解决方案很明显。我们不是在等待 SignalR 发挥其重新连接的魔力。相反,当应用程序被激活或手机的网络连接恢复时,我们只是清理事件并取消引用 HubConnection (无法释放它,因为它需要 30 秒,希望垃圾收集会处理它) 并创建一个新实例。现在一切都很好。出于某种原因,我认为我们应该重用持久连接并重新连接,而不是仅仅创建一个新实例。