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

Posted

技术标签:

【中文标题】为啥我的 NSURLSessionDownloadTask 下载不会到达我的客户端?【英文标题】:Why won't my NSURLSessionDownloadTask download ever reach my client?为什么我的 NSURLSessionDownloadTask 下载不会到达我的客户端? 【发布时间】:2016-11-08 02:49:49 【问题描述】:

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

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

    我们无法在任何 Safari 浏览器(桌面或 iOS)中下载相同的 XML 我们可以在桌面上使用 Chrome 下载 XML 我们可以在命令行使用 curl 下载 XML 在我们的 iOS 应用程序中,无法将 XML 下载到设备或模拟器中

我同时调高了 timeoutIntervalForRequest 和 timeoutIntervalForResource。它本身并不是“超时”。但是,Apple 的网络堆栈中的某些东西似乎不允许长时间等待服务器生成 XML。为什么 Chrome 和 curl 没有问题,但 Safari 和我的 iOS 代码有问题?所以,我对这里发生的事情有些茫然。

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

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

【问题讨论】:

我也尝试过 AFNetworking 和 curl,它们在一个项目中都失败了。但是我可以在终端中运行相同的 curl 并且它可以工作。 【参考方案1】:

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

即使您可以调整参数以减少问题,也很有可能唯一真正的答案是“更改服务器”,这仅仅是因为(尤其是在蜂窝连接上)网络连接断开的可能性非零随机。

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

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

或使用 UUID 参数:

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

这可能是 10 行代码——20 行代码——加上一个两行的 cron 脚本,用于清理超过一天前的任何文件。

然后,您的应用可以请求数据并取回 UUID。然后,它可以定期询问服务器是否有数据,它会立即回复说“这是数据”或“不,还没有”。

【讨论】:

有趣的回复,谢谢!是的,我将两个超时值都设置得很高。

以上是关于为啥我的 NSURLSessionDownloadTask 下载不会到达我的客户端?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Chrome Profiler 没有为我的对象显示正确的保留路径,为啥我的对象从未被释放?

为啥我的程序需要两行输入,为啥我的 GPA 计算错误 c#?

为啥我的 PHP 会话会死掉?为啥我不能恢复它们?

为啥我的碰撞测试总是返回“真”,为啥图像矩形的位置总是错误的 (0, 0)?

NPM 启动错误上的 ENOENT。为啥我会收到此错误,为啥要查找“我的图片”目录?

为啥 main 前面有一个 int ,为啥我的教授会排除它? [复制]