2015-05-07 109 views
8

在我的iOS應用中,我有一個從服務器獲取結果的搜索功能。搜索更新會在用戶更新其查詢時進行更新,因此會導致連續發出多個請求。iOS和Go-Keep-Alive使用NSURLSession

所以我的問題是,我如何確保在這些連接上使用TCP保持連接?我希望減少儘可能多的延遲,所以重要的是在第一次請求後保持連接併爲以下請求重新使用。

我正在使用NSURLSession,並且我聽說它默認採用保持活動狀態,但我怎麼知道確切的?在服務器上記錄請求顯示每個連續請求之間沒有區別,但我不希望僅從頭信息中看到任何更改。

這裏有什麼幫助嗎?我在我的服務器上使用Go,因此可能需要在該端進行一些額外的配置。

回答

6

我相信你讓TCP keep-alive與HTTP keep-alive(持久連接)混淆。這些都是不相關的概念。從你的問題,你可能意味着HTTP持久連接。

在HTTP/1.1中,持久連接是默認連接,由NSURLSession和幾乎所有HTTP/1.1客戶端使用。你必須要求關閉它們。您可以在HTTP頭部或服務器端檢查Connection: close,您可以檢查http.RequestClose字段。但我相信你會獲得持久的聯繫。這意味着您不必爲每個請求重新協商TLS隧道(或至少TCP三次握手)。 (儘管如果你發出並行請求,仍然會有多個連接需要協商,HTTP/1.1一次只能處理一件事,NSURLSession會嘗試使用連接池來提高響應時間。)

TCP保活是完全不同的事情。它向對方發送一個週期性的「ping」,以確保它仍然可以訪問。在下次嘗試進行通信之前,有很多方法可能導致網絡連接中斷,並且無法識別它,而正常情況下,連接只是掛起,您需要將其斷開。理論上,TCP保持活躍只是發現這一點的工具,但我幾乎從未發現它是實用的。很難正確配置(特別是在可可中)。您幾乎總是需要爲應用程序構建更高級別的「ping」功能,而不是依賴此功能。

但是把它帶到你的問題,HTTP/1.1對你來說可能是好的,但你需要仔細管理你的回答。如果您對每封信都提出新的要求併發回大量回復,那麼這將會非常糟糕。你會保持所有的連接池都忙於下載你要扔掉的東西。您需要首先關注優秀的算法。至少,您可能只想一次發送一些結果,並在API中提供「分頁」方法,以便爲相同搜索請求更多結果。

+0

感謝您的有用信息。自問題提出後,我在算法上做了一些重大改進,最重要的是實現了一個計時器,以便搜索只在用戶暫時停止鍵入時發送請求。但我很好奇你提到的「分頁」方法 - 你能澄清你的意思嗎? – hundley

+1

@hundley分頁意味着如果結果數量不止一個,則只返回第一個集合,在稍後的批次中通過附加一個具有所需「頁面」的請求變量來檢索。想想Google的結果是如何分批的。只有當結果的數量很大時才重要。你的「等待暫停」是一種非常常見的技術,非常有幫助。 –

6

要確切知道TCP在做什麼,可以啓用CFNETWORK_DIAGNOSTICS。從文檔:

在正常開發過程中,您可以通過Xcode的方案編輯器設置此環境變量。如果您需要調查Xcode之外的問題,可以使用清單1中顯示的代碼以編程方式進行設置。

清單1編程使CFNetwork的診斷日誌

setenv("CFNETWORK_DIAGNOSTICS", "3", 1); 

您應該在應用啓動序列的開始這樣做的權利。通常把這個放在main的開頭就足夠了,但是如果你有使用CFNetwork的C++靜態初始化器,你必須在它們之前運行它。

CFNetwork的診斷日誌啓動時首先使用CFNetwork的-或任何框架,像基金會,使用CFNetwork的-,在該點它將打印清單2.

清單2的例子中所示的那樣的消息CFNetwork診斷記錄啓動消息

2014-10-28 14:23:37.115 QTestbed[2626:60b] CFNetwork diagnostics log file created at: /private/var/mobile/Applications/76531F40-3291-4565-8C75-0438052C83BC/Library/Logs/CrashReporter/CFNetwork_com.example.apple-samplecode.QTestbed_2626.nwlrb