[英]Sending SPDY requests results in "The request timed out" errors with NSUrlSession in iOS
我的 iOS 應用程序從 nginx HTTP 服務器加載圖像。 在我發送了 400 多個這樣的請求后,網絡“卡住了”,所有后續的 HTTP 請求都會導致“請求超時”錯誤。 只有當我重新啟動應用程序時,我才能再次加載圖像。
細節:
NSURLSession.sharedSession().dataTaskWithURL
向 jpeg 文件發送四百個 HTTP GET 請求。NSURLSessionDataTask
對象的cancel()
方法取消每個先前未完成的請求。有趣的是:
問題的原因是什么? 任何人都可以推薦其他方法或工具來分析和調試它嗎?
這個演示應用程序 100% 地為我重現了這個問題。
https://github.com/exchangegroup/ImageLoadDemo
我的 nginx 配置: http : //pastebin.com/pYYjdxfP
OS X :10.10.4 (14E46), iOS :8 和 9, Xcode :7.0 (7A218), nginx :1.9.4
只有當我為每個單獨的請求創建一個新的 NSURLSession 並使用finishTasksAndInvalidate
或invalidateAndCancel
清除上一個會話時,我才設法保持請求工作。
// Request 1
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration)
session.dataTaskWithURL ...
// Request 2
// clear the previous request
session.finishTasksAndInvalidate()
let session2 = NSURLSession(configuration: configuration)
session2.dataTaskWithURL ...
一種可能是 iOS 開始發送請求,然后丟包導致 headers 和 request body 無法完全傳遞。
想到的另一種可能性是,您的服務器在實際完成嘗試交付之前可能不會記錄請求,這將使服務器日志中的時間戳與連接關閉的時間對齊,而不是連接打開的時間. (IIRC,這就是 Apache 所做的;我沒有使用過 nginx,所以我不能說它的行為。)如果是這種情況,那么這只是一個簡單的連接停頓。 至於為什么會卡頓,我猜不出來。
問題是否僅針對 HTTPS 流量發生? 如果你可以用 HTTP 重現它,你就不需要 Charles Proxy; 只需使用 OS X 的“Internet 共享”功能,並使用 tcpdump 或 wireshark 捕獲數據包,監聽橋接接口。 如果你不能用 HTTP 重現它,我的錢將用於獲取 CRL 或在驗證服務器證書時執行 OCSP 檢查的問題。
您的應用程序是否會因向新隊列過度異步調度而導致大量線程? 因為那很容易導致各種奇怪的不當行為。
超時時間是多久? 如果它太短,您的應用程序可能只是在運行時遇到硬件的性能限制,同時處理僅在四秒鍾內交付的 400 個請求的結果。
另外,您是否嘗試同時安排這些請求? 因為我似乎記得讀過一個錯誤,如果你在一個會話中同時啟動太多任務,它會導致 NSURLSession 撞到磚牆。 您可以僅在會話中的任務數量低於某個閾值后嘗試添加任務,看看是否能解決問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.