为什么我的NSURLSessionDownloadTask下载不会到达我的客户端?

时间:2016-11-08 02:49:49

标签: ios google-chrome curl safari nsurlsessiondownloadtask

我的iOS应用程序使用NSURLSessionConfiguration,NSURLSession,NSURLSessionDownloadTask等来下载我们的服务器从数据库中即时生成的xml文件。下载后一切正常,直到我尝试从一个特定帐户下载更大的文件。我们的服务器在为此帐户提供xml之前必须做很多工作。换句话说,在服务器实际吐出请求的xml之前,有一个有点重要的等待。对于这个最大的帐户,即使服务器成功处理数据并将报告发送到客户端,iOS客户端也永远不会收到数据。

在测试时,我们发现了一些特殊的东西:

  1. 我们无法在任何Safari浏览器(桌面或iOS)中下载相同的XML
  2. 我们可以在桌面上使用Chrome下载XML
  3. 我们可以在命令行上使用curl下载XML
  4. 在我们的iOS应用中,它无法在设备或模拟器中下载XML
  5. 我启动了timeoutIntervalForRequest和timeoutIntervalForResource。它本身并不是“超时”。但看起来Apple的网络堆栈中的某些内容似乎不允许服务器长时间等待XML生成。为什么Chrome和curl没有问题,但Safari和我的iOS代码呢?所以,我对这里发生的事情感到有些不知所措。

    这是旧版服务器代码,将来会更改为JSON和更快的类,因此我不需要任何“更改您的服务器代码”答案。

    对我有什么想法?提前谢谢。

1 个答案:

答案 0 :(得分:2)

你有两次超时;第一个是在特定时间段内没有数据时。另一个是在请求未在特定时间段内完成时。这两者都需要足够高。我的猜测是,服务器甚至不会在第一次超时内发送回状态代码,这会导致NSURL堆栈假定服务器已经死亡。

即使您可以调整参数以减少问题,但很有可能唯一真正的答案是更改服务器",仅仅因为有非零的机会(特别是在蜂窝连接上)网络连接会随机丢失。

解决这个问题的最简单方法是编写一个没有参数的小包装脚本:

  • 立即返回资源的唯一标识符(UUID)。
  • 生成一个异步卷曲作业(在服务器上)从服务器请求资源并将其写入文件,该UUID作为名称
  • 存储libcurl在My-UUID-Goes-Here.meta或类似内容中提供的预期文件长度。
  • 如果出现任何问题,请删除该文件。

或使用UUID参数:

  • 确保UUID是一个没有任何特殊字符的正确UUID。
  • 检查特定目录中是否存在具有该UUID的文件,并验证该文件是否完整。
  • 如果文件不完整,则提供接收的字节数和预期的总字节数(或者只是说"未准备就绪")。
  • 否则,返回文件并立即将其删除。

它可能是十行代码 - 二十个顶部 - 加上可能是一个两行的cron脚本来清理任何超过一天的文件。

然后,您的应用程序可以只询问数据并返回UUID。然后,它可以定期询问服务器是否还有数据,然后它会返回一个即时响应,其中包含以下数据"这里是数据"或者"不。尚未"。