我终于搞明白了。自从开始提出这个问题以来,我学到了以下内容:
背景:我们正在使用Xamarin/Monotouch和.NET SignalR 2.0.3客户端构建一个iOS应用程序。我们使用默认的SignalR协议-似乎是使用SSE而不是WebSockets。我还不确定在Xamarin / Monotouch中是否可以使用WebSockets。所有内容都是使用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中,30秒后触发Closed()事件,在场景C中立即触发;在这些重新连接等待期间,State属性显示“Connected”,没有其他相关事件或方法)
解决方案:
解决方案很明显。我们不再等待SignalR的重新连接魔法。相反,当应用程序被激活或手机网络连接恢复时,我们只需清理事件并取消引用HubConnection(不能处置它,因为需要30秒,希望垃圾回收会处理它),并创建一个新实例。现在一切都很好。出于某种原因,我认为我们应该重用持久连接并重新连接,而不仅仅是创建一个新实例。