【问题标题】:Android/Xamarin.Android rest client timeout when switching network from wifi to 3g将网络从 wifi 切换到 3g 时 Android/Xamarin.Android 休息客户端超时
【发布时间】: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.

重现的步骤列表如下:

  1. 使用 wifi 在手机上启动应用程序
  2. 尝试检索数据。这应该会导致成功 检索
  3. 使用快速设置栏(从屏幕顶部下拉),转动 wifi 关闭,以便您使用蜂窝数据
  4. 再次尝试检索数据(尝试并等待 你想要....1 秒、10 秒、2 分钟产生相同的结果 结果)。这应该会导致失败(在 servicestack 客户端 它会导致超时,在 httpclients 上会导致 OperationCancelledException,这一切都是超时)
  5. 在尝试检索数据并在 第一次尝试,再试一次,你应该会成功。

我们更喜欢在我们的应用程序中使用 ServiceStack 客户端,因为它隐藏了很多复杂的代码。通过对该问题的研究,大量信息表明我们使用了一个名为 ModernHttpClient 的库(此错误描述了我们的确切步骤,但据报道与 iOS 相关),但这并不能解决我们的问题。

还可以在此处找到这些步骤的视频截屏视频。要查看此视频的示例截屏视频,请观看此视频https://drive.google.com/open?id=0B9ulyVqWgbL3aEUzVFJEYTF2dEk。 上述截屏中使用的简单示例应用程序可以在https://drive.google.com/open?id=0B9ulyVqWgbL3UHZmX2x6NDBEY00找到。

你们中有人知道这是 Android 操作系统问题、单声道问题还是代码问题……还是其中的几个问题?有解决办法吗?

编辑:另一个有趣的尝试场景。

  1. 使用 wifi 在手机上启动应用程序
  2. 尝试检索数据。这应该会导致成功 检索
  3. 使用快速设置栏(从屏幕顶部下拉),转动 wifi 关闭,以便您使用蜂窝数据
  4. 进入飞行模式
  5. 退出飞行模式
  6. 再次尝试检索数据。这将导致成功

【问题讨论】:

  • 当设备更改网络并且不知道它时,似乎正在保持一些连接。您可以向 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,我添加了答案:)

标签: android xamarin mono network-programming xamarin.forms


【解决方案1】:

问题是改网络后客户端重用连接,当然连接是无效的。

您可以通过将 KeepAlive 设置为 false 到 HttpWebRequest 来添加“内容:关闭”,但不能从 PCL 程序集中完成。

因此你必须创建一个从 PCL 到 ios/android 项目的 Dependency,将请求发送到本机端,将 KeepAlive 设置为 false 并返回,这样连接将关闭,当你创建新连接时它会关闭在新网络上。

【讨论】:

  • 需要注意的一点是,对于 ServiceStack,我使用的是 JsonServiceClient。类或实例对象上都有一个名为“RequestFilter”的属性。为了能够使用依赖服务更改请求的标头,您需要能够将请求对象传递给依赖服务。 RequestFilter 的签名是“Action{ // 在这里处理请求 }"
猜你喜欢
  • 1970-01-01
  • 2017-04-29
  • 2013-08-21
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
相关资源
最近更新 更多