将网络从 wifi 切换到 3g 时 Android/Xamarin.Android 休息客户端超时
Posted
技术标签:
【中文标题】将网络从 wifi 切换到 3g 时 Android/Xamarin.Android 休息客户端超时【英文标题】:Android/Xamarin.Android rest client timeout when switching network from wifi to 3g 【发布时间】:2016-05-14 04:42:53 【问题描述】:我的团队正在使用 Xamarin 表单(主要针对手机)开展依赖网络连接的项目。我们在 android 上遇到了一个问题,它抑制了我们应用程序的一个主要功能。当我们从 wifi 切换到蜂窝后尝试访问数据服务时,我们经常会在第一次数据检索尝试时收到超时错误。随后的尝试奏效。 这个问题不会反过来发生(从移动设备到 wifi)。 This bug describes our problem, but says it's for ios, and interestingly enough we dont get this issue on iOS.
重现的步骤列表如下:
-
使用 wifi 在手机上启动应用程序
尝试检索数据。这应该会导致成功
检索
使用快速设置栏(从屏幕顶部下拉),转动
wifi 关闭,以便您使用蜂窝数据
再次尝试检索数据(尝试并等待
你想要....1 秒、10 秒、2 分钟产生相同的结果
结果)。这应该会导致失败(在 servicestack 客户端
它会导致超时,在 httpclients 上会导致
OperationCancelledException,这一切都是超时)
在尝试检索数据并在
第一次尝试,再试一次,你应该会成功。
我们更喜欢在我们的应用程序中使用 ServiceStack 客户端,因为它隐藏了很多复杂的代码。通过对该问题的研究,大量信息表明我们使用了一个名为 ModernHttpClient 的库(此错误描述了我们的确切步骤,但据报道与 iOS 相关),但这并不能解决我们的问题。
还可以在此处找到这些步骤的视频截屏视频。要查看此视频的示例截屏视频,请观看此视频https://drive.google.com/open?id=0B9ulyVqWgbL3aEUzVFJEYTF2dEk。 上述截屏中使用的简单示例应用程序可以在https://drive.google.com/open?id=0B9ulyVqWgbL3UHZmX2x6NDBEY00找到。
你们中有人知道这是 Android 操作系统问题、单声道问题还是代码问题……还是其中的几个问题?有解决办法吗?
编辑:另一个有趣的尝试场景。
-
使用 wifi 在手机上启动应用程序
尝试检索数据。这应该会导致成功
检索
使用快速设置栏(从屏幕顶部下拉),转动
wifi 关闭,以便您使用蜂窝数据
进入飞行模式
退出飞行模式
再次尝试检索数据。这将导致成功
【问题讨论】:
当设备更改网络并且不知道它时,似乎正在保持一些连接。您可以向 ServiceStack 客户端添加 connection: close 标头吗?这样,您将确保连接没有被重复使用,并且可以避免这个问题 @Gusman 我喜欢这个想法,并且在 System.Net.HttpClient(PCL 版本)上我可以添加这个只是找到。但是,ServiceStack 使用 HttpWebRequest,当我尝试添加标头时,它会引发异常“System.ArgumentException:此标头必须使用适当的属性进行修改”。不幸的是,PCL HttpWebRequest(或至少单声道 PCL 版本)没有公开 Connection 属性或 HttpWebRequest 的 KeepAlive 属性 我认为您正在创建一个表单应用程序。如果是这种情况,那么添加标题并不是很困难(只是有点费力)。 1-为每个示例 IHttpRequestManipulator 创建一个接口,其中一个公共函数接受 HttpWebRequest 作为参数。 2-在android或ios项目上添加一个继承自接口的类,并在函数中将KeepAlive设置为false。 3-将该类注册为 Xamarin DependencyService 的依赖项。 4-当你需要将keepalive设置为false时,从依赖服务中获取服务,传递请求,它将keepalive更改为false @Gusman ,感谢您的回复,这有效。如果我可以要求您将答案放在答案部分,以便我可以选择它作为答案给您代表,那就太好了!再次感谢您! 谢谢@Benji,我添加了答案:) 【参考方案1】:问题是改网络后客户端重用连接,当然连接是无效的。
您可以通过将 KeepAlive 设置为 false 到 HttpWebRequest 来添加“内容:关闭”,但不能从 PCL 程序集中完成。
因此你必须创建一个从 PCL 到 ios/android 项目的 Dependency,将请求发送到本机端,将 KeepAlive 设置为 false 并返回,这样连接将关闭,当你创建新连接时它会关闭在新网络上。
【讨论】:
需要注意的一点是,对于 ServiceStack,我使用的是 JsonServiceClient。类或实例对象上都有一个名为“RequestFilter”的属性。为了能够使用依赖服务更改请求的标头,您需要能够将请求对象传递给依赖服务。 RequestFilter 的签名是“Action以上是关于将网络从 wifi 切换到 3g 时 Android/Xamarin.Android 休息客户端超时的主要内容,如果未能解决你的问题,请参考以下文章