超時處理
我們都有在網(wǎng)絡(luò)不太好的情況下使用 app 的經(jīng)歷拂蝎。很多 app 大概 15 秒左右就會結(jié)束請求并且反饋一個超時信息穴墅。這種設(shè)計其實是很不友好的。應(yīng)該給用戶一個他們可以理解的友好提示温自,諸如“你好封救,現(xiàn)在網(wǎng)絡(luò)狀況不太好,您需要多等一會兒捣作。”鹅士。但是即便網(wǎng)絡(luò)狀況不好券躁,只要連接還在,TCP 都會保證將請求發(fā)出去并且會一直等待響應(yīng)的返回掉盅,只是時間長短的問題也拜。
從另一個角度來說:在較慢的網(wǎng)絡(luò)中,請求-響應(yīng)的RTT時間可能會有 17 秒趾痘。如果 15 秒就決定中止請求慢哈,就算用戶有足夠的耐心,他們也沒機(jī)會等到想要的操作結(jié)果永票。反過來卵贱,如果我們給出用戶相應(yīng)的提示信息滥沫,而他們又剛好愿意多等一會,用戶可能會更喜歡使用這樣的應(yīng)用键俱。
一直以來都有一種誤解兰绣,用重發(fā)請求來解決上面的問題。注意编振,這不是問題的關(guān)鍵缀辩,因為 TCP 有自己的重發(fā)機(jī)制。
正確的處理方式應(yīng)該是:每當(dāng)發(fā)起一個請求的時候踪央,同時啟動一個 10 秒計時器臀玄。如果請求在 10 秒之內(nèi)返回,就把計時器停掉畅蹂。如果超過 10 秒健无,可以給用戶一個提示“網(wǎng)絡(luò)不好,請稍后魁莉〔墙В”,我建議再給用戶一個取消按鈕旗唁,讓他們可以自行選擇等待還是取消請求畦浓,當(dāng)然提示信息的具體內(nèi)容和是否配備取消按鈕,這個可以視乎各 app 的情況去決定检疫⊙惹耄總而言之,開發(fā)者最好不要直接替用戶做決定屎媳,比如直接中止他們的請求夺溢。
只要連接雙方的 IP 地址是不變的、可用的烛谊,連接就一定會是“活躍”的风响。如果把 iPhone 從 Wi-Fi 連接切換到 3G 網(wǎng)絡(luò),這樣連接就會變得不可用丹禀,因為手機(jī)的 IP 地址發(fā)生了變化状勤,基于原 IP 地址創(chuàng)建的路由自然是失效的。
緩存
看看第一個例子中發(fā)送的這段 header 信息:
If-None-Match: "a54907f38b306fe3ae4f32c003ddd507"
這表示客戶端本地已經(jīng)針對所請求的資源做過緩存了双泪,如果服務(wù)器上的資源有過更新持搜,需要將最新的資源返回給客戶端,否則不需要返回焙矛。如果自己構(gòu)建客戶端和服務(wù)器的數(shù)據(jù)通信葫盼,建議充分利用這個機(jī)制。這種機(jī)制叫做 HTTP ETag村斟,如果使用得當(dāng)贫导,會對通訊的速度有明顯的優(yōu)化抛猫。
記住“最快的請求是不發(fā)請求”。舉個極端的例子脱盲,拿一個請求來說邑滨,哪怕你有最好的網(wǎng)絡(luò),請求的數(shù)據(jù)量極小钱反,有超快的服務(wù)器掖看,你也不大可能在 50ms 內(nèi)拿到請求的響應(yīng)。這還只是一個請求面哥。想想吧哎壳,如果有可能在本地創(chuàng)建相同的數(shù)據(jù),而且耗時小于 50ms尚卫,那就不要發(fā)這樣的請求归榕。
針對已請求的資源,只要服務(wù)器上對應(yīng)的資源具備在一定時間內(nèi)不發(fā)生變化特性吱涉,建議在本地緩存起來刹泄。注意檢查 header 中緩存過期的相關(guān)屬性,也可以直接利用 NSURLSession 中的 NSURLRequestUseProtocolCachePolicy 策略怎爵。