共享AFHTTPSessionManager 單例好處淺析

  不少時候,AFNetworking都是目前iOS開發者網絡庫中的不二選擇。Github2W+star數足見其流行程度。而從iOS7.0開始,蘋果推出了新的網絡庫繼承者NSURLSession後,AFNetworking也堅決果斷地加入了對其的支持。3.0+更加只是提供了NSURLSession的支持。git

  咱們使用AFNetworking的時候,可能會有不少的朋友都會採用如下的寫法:github

AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager]; sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer]; sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer]; [sessionManager GET:urlString parameters:parameters progress:progressBlock success:successHandler failure:failureHandler];

  大概能夠描述一下這個過程,每次開啓一個網絡請求時,首先新建一個AFHTTPSessionManager,而後將相關的requestSerializerreponseSerializer賦值;最後發起相應的GET/POST等請求。sql

  而若是是直接採用NSURLSession來請求網絡呢,咱們則常常會採用如下的寫法:ruby

NSURLSession *session = [NSURLSession sessionWithConfiguration: [NSURLSessionConfiguration defaultSessionConfiguration] delegate:nil delegateQueue:[NSOperationQueue mainQueue]]; NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:completionHandler]; [dataTask resume];

  這個過程其實和上面的基本一致。新建一個Session,而後新建task,激活task,完成網絡請求。服務器

  那麼如今問題來了。爲何每次都須要新建一個SessionManager/Session?若是在多個Task請求的狀況下,若是採起一個共享的SessionManager/Session是否可行?若是可行,與以前每次新建SessionManager/Session相比,孰優孰劣?網絡

  本篇文章會告訴您
  1. 爲何要使用NSURLSession而不是NSURLConnection
  2. 爲何要用共享的SessionManager/Session,而不是每次都啓動一個新的 session

爲何要選擇NSURLSession

  NSURLSessioniOS7.0時被Apple提出後,雖然Apple一直對其良好的API設計大力推廣,然而其可以達到的效果,彷佛一直都和NSURLConnection不相伯仲。 架構

  特別是在網絡的Dependecy依賴處理上,因爲AFNetworking優秀的架構設計,NSURLSession甚至還不如NSURLConnection好用。那麼,有什麼理由切換到NSURLSession? 2015年的WWDC彷佛告訴了咱們答案。 併發

  HTTP /2, 2015年5月RFC 7540正式發表的下一代HTTP協議,是1999年來HTTP 1.1發佈後的首個更新。相對於前一個版本,HTTP /2著稱。以下圖,對相同圖片、相同服務器的下載,在不一樣協議下所需的時間: app


http2

  這裏咱們並不打算展開HTTP /2的原理,有興趣的同窗能夠Google之。根據2015的WWDC Session711,咱們知道iOS9+NSURLSession開始正式支持HTTP /2,也就意味着你的網絡鏈接速度也能夠有如上圖那樣的提高。

  更人性化更優秀的API設計,HTTP /2的支持,這是否能成爲你使用NSURLSession的理由?至少它們成爲了說服個人理由。

爲何要儘可能共享Session,而不是每次新建Session

  在回答這個問題之前,咱們先來聊聊網絡的通信協議。咱們也都知道,HTTP協議是基於TCP協議的。因此在每次的HTTP請求以前,客戶端和服務器端,都先須要通過TCP鏈接的三次握手,即每次請求以前,網絡的數據都已經在客戶端和服務器端之間來回了三次。以下圖:


TCP三次握手(圖片來源於網絡)

  事實上在HTTP 0.9, HTTP 1.0協議的時代,每次HTTP的請求,都須要先通過TCP的鏈接,而後纔開始HTTP的請求,這樣一個流程圖,咱們能夠經過抓包看到:


抓包

  那麼,爲了讓咱們的請求更快,避免每次都產生一個TCP三次握手,成了一個優化的選項。因而在HTTP 1.1中,出現了Connection: keep-alive這個選項。這個優化選項,可使得客戶端和服務器端複用一個TCP鏈接,從而減少每次的網絡請求時間。


非共享Session

共享Session

  聊到這裏,本章提出的問題,其實答案已經逐漸明瞭了。沒錯,共享的Session將會複用TCP的鏈接,而每次都新建Session的操做將致使每次的網絡請求都開啓一個TCP的三次握手。

  從上面兩張圖,咱們能夠清晰地看到,一樣都是兩次HTTP請求,共享Session的代碼在第二次網絡請求時少了TCP的三次握手的過程。即加速了整個網絡的請求時間。

  事實上,蘋果的文檔中,還對一個服務器最高的TCP併發有相應的描述:

HTTPMaximumConnectionsPerHost  Property
The maximum number of simultaneous connections to make to a given host.

Declaration
SWIFT
    var HTTPMaximumConnectionsPerHost: Int
OBJECTIVE-C
    @property NSInteger HTTPMaximumConnectionsPerHost
Discussion
This property determines the maximum number of simultaneous connections made to each host by tasks within sessions based on this configuration.

This limit is per session, so if you use multiple sessions, your app as a whole may exceed this limit. Additionally, depending on your connection to the Internet, a session may use a lower limit than the one you specify. The default value is 6 in OS X, or 4 in iOS. Availability Available in iOS 7.0 and later.

  咱們能夠看到,默認配置下,iOS對於同一個IP服務器的併發最大爲4OS X6。而若是你沒有使用共享的Session,則可能會超過這個數。

  所以,若是能用共享的Session,仍是用共享的吧。有些許的網絡加速,也是一件不錯的事情,您說呢?

 




參考連接:
1.http://www.jianshu.com/p/5969bbb4af9f

2.http://www.jianshu.com/p/a9bca62d8dab
相關文章
相關標籤/搜索