后台 URLSession 卡住了
Background URLSession stuck
我正在使用 URLSession 将大量文件上传到服务器,因为上传的文件可能很大我正在使用 URLSessionConfiguration.background
以便我的上传可以在后台继续。
我的 url 会话声明如下:
urlSessionConfiguration = URLSessionConfiguration.background(withIdentifier: UploadQueue.uploadQueueIdentifier)
urlSessionConfiguration.sessionSendsLaunchEvents = true
urlSessionConfiguration.shouldUseExtendedBackgroundIdleMode = true
urlSessionConfiguration.allowsCellularAccess = true
urlSessionConfiguration.sharedContainerIdentifier = appGroup
backgroundUploadSession = URLSession(configuration: urlSessionConfiguration, delegate: self, delegateQueue: nil)
URLSessionUploadTask
总是在前台创建(我们使用后台会话只是为了确保任务可以完成)。
var request = try! URLRequest(url: url, method: .put)
backgroundUploadSession.uploadTask(with: request, fromFile: fileUrl).resume()
当上传 ~ 100 个文件并留在前台时,所有必要的委托都已实现并正常调用。
然而,当上传大量文件(~1000)时,第一个文件正确上传但一段时间后会话似乎“卡住”并且没有回调被传递。 (仍然在前台使用应用程序)
我注意到如果我只是等待上传会在 ~5 分钟后重新开始。
我尝试用 URLSessionConfiguration.default
替换 URLSessionConfiguration.background(withIdentifier: UploadQueue.uploadQueueIdentifier)
,它在前台运行良好。
这是 URLSessionConfiguration.background 的错误还是我做错了什么?
经过调查发现有多个问题:
- 我们原以为
URLSessionConfiguration.httpMaximumConnectionsPerHost
会限制打开的连接数。但是,当使用 http/2 或服务器位于代理后面时,似乎没有遵守此限制。
解决方案:进行自己的连接限制(例如使用 DispatchGroup)
- 即使限制并发上传的数量,即使应用程序处于 前台,后台会话也会在一段时间后卡住。后台会话有一个速率限制器,但文档说当应用程序在后台时它不被认可。
解决方案:这是 discussed on Apple Developer Forum,这是 CF 网络框架中的错误。已提交错误报告。目前,解决方案是简单地不要创建太多带有小文件的后台会话。
我正在使用 URLSession 将大量文件上传到服务器,因为上传的文件可能很大我正在使用 URLSessionConfiguration.background
以便我的上传可以在后台继续。
我的 url 会话声明如下:
urlSessionConfiguration = URLSessionConfiguration.background(withIdentifier: UploadQueue.uploadQueueIdentifier)
urlSessionConfiguration.sessionSendsLaunchEvents = true
urlSessionConfiguration.shouldUseExtendedBackgroundIdleMode = true
urlSessionConfiguration.allowsCellularAccess = true
urlSessionConfiguration.sharedContainerIdentifier = appGroup
backgroundUploadSession = URLSession(configuration: urlSessionConfiguration, delegate: self, delegateQueue: nil)
URLSessionUploadTask
总是在前台创建(我们使用后台会话只是为了确保任务可以完成)。
var request = try! URLRequest(url: url, method: .put)
backgroundUploadSession.uploadTask(with: request, fromFile: fileUrl).resume()
当上传 ~ 100 个文件并留在前台时,所有必要的委托都已实现并正常调用。 然而,当上传大量文件(~1000)时,第一个文件正确上传但一段时间后会话似乎“卡住”并且没有回调被传递。 (仍然在前台使用应用程序) 我注意到如果我只是等待上传会在 ~5 分钟后重新开始。
我尝试用 URLSessionConfiguration.default
替换 URLSessionConfiguration.background(withIdentifier: UploadQueue.uploadQueueIdentifier)
,它在前台运行良好。
这是 URLSessionConfiguration.background 的错误还是我做错了什么?
经过调查发现有多个问题:
- 我们原以为
URLSessionConfiguration.httpMaximumConnectionsPerHost
会限制打开的连接数。但是,当使用 http/2 或服务器位于代理后面时,似乎没有遵守此限制。
解决方案:进行自己的连接限制(例如使用 DispatchGroup)
- 即使限制并发上传的数量,即使应用程序处于 前台,后台会话也会在一段时间后卡住。后台会话有一个速率限制器,但文档说当应用程序在后台时它不被认可。
解决方案:这是 discussed on Apple Developer Forum,这是 CF 网络框架中的错误。已提交错误报告。目前,解决方案是简单地不要创建太多带有小文件的后台会话。