IM 即時通訊技術(shù)在多應用場景下的技術(shù)實現(xiàn)娇钱,以及性能調(diào)優(yōu)(iOS視角)
(視頻見評論區(qū))
2016年9月份我參加了 MDCC2016(中國移動開發(fā)者大會),
在 MDCC2016 上我做了關(guān)于 IM 相關(guān)分享并扇,會上因為有50分鐘的時間限制 去团,所以有很多東西都沒有展開,這篇是演講稿的博文版本穷蛹,比會上講得更為詳細土陪。有些演講時一筆帶過的部分,在文中就可以展開講講肴熏。
注:
- 本文中所涉及到的所有 iOS 端相關(guān)代碼鬼雀,均已100%開源(不存在 framework ),便于學習參考扮超。
- 本文側(cè)重移動端的設計與實現(xiàn)取刃,會展開講蹋肮,服務端僅僅屬于概述出刷,不展開。
- 為大家在設計或改造優(yōu)化 IM 模塊時坯辩,提供一些參考馁龟。
我現(xiàn)在任職于 LeanCloud(原名 AVOS
) 。LeanCloud 是國內(nèi)較早提供 IM 服務的 Paas 廠商漆魔,提供 IM 相關(guān)的 SDK 供開發(fā)者使用坷檩,現(xiàn)在采納我們 IM 方案的 APP 有:知乎Live却音、掌上鏈家、懂球帝等等矢炼,在 IM 方面也積累了一些經(jīng)驗系瓢,這次就在這篇博文分享下。
IM系列文章
IM 系列文章分為下面這幾篇:
- 《IM 即時通訊技術(shù)在多應用場景下的技術(shù)實現(xiàn)句灌,以及性能調(diào)優(yōu)(iOS視角)》 (本文)
- 《技術(shù)實現(xiàn)細節(jié)》
- 《有一種 Block 叫 Callback夷陋,有一種 Callback 做 CompletionHandler》
- 《防 DNS 污染方案》
本文是第一篇。
提綱
大規(guī)模即時通訊技術(shù)上的難點
思考幾個問題:
- 如何在移動網(wǎng)絡環(huán)境下優(yōu)化電量,流量资昧,及長連接的健壯性酬土?現(xiàn)在移動網(wǎng)絡有2G、3G格带、4G各種制式撤缴,并且隨時可能切換和中斷,移動網(wǎng)絡優(yōu)化可以說是面向移動服務的共同問題叽唱。
- 如何確保IM系統(tǒng)的整體安全腹泌?因為用戶的消息是個人隱私,因此要從多個層面來保證IM系統(tǒng)的安全性尔觉。
- 如何降低開發(fā)者集成門檻凉袱?
- 如何應對新的iOS生態(tài)下的政策以及結(jié)合新技術(shù):比如HTTP/2、IPv6侦铜、新的APNs協(xié)議等专甩。
應用場景
一個 IM 服務最大的價值在于什么?
可復用的長連接钉稍。一切高實時性的場景涤躲,都適合使用IM來做。
比如:
- 視頻會議贡未、聊天种樱、私信
- 彈幕、抽獎
- 互動游戲
- 協(xié)同編輯
- 股票基金實時報價俊卤、體育實況更新嫩挤、
- 基于位置的應用:Uber、滴滴司機位置
- 在線教育
- 智能家居
下文會挑一些典型的場景進行介紹消恍,并涉及到技術(shù)細節(jié)岂昭。
IM 發(fā)展史
基本的發(fā)展歷程是:輪詢、長輪詢狠怨、長連接约啊。
挑一些代表性的技術(shù)做下介紹:
一般的網(wǎng)絡請求:一問一答
輪詢:頻繁的一問一答
長輪詢:耐心地一問一答
一種輪詢方式是否為長輪詢邑遏,是根據(jù)服務端的處理方式來決定的,與客戶端沒有關(guān)系恰矩。
短輪詢很容易理解记盒,那么什么叫長輪詢?與短輪詢有什么區(qū)別外傅。
舉個例子:
比如中秋節(jié)我們要做一個秒殺月餅的頁面孽鸡,要求我們要實時地展示剩余的月餅數(shù)量,也就是庫存量栏豺。這時候如果要求你只能用短輪詢或長輪詢?nèi)プ霰蚣睿趺醋瞿兀?/p>
長輪詢和短輪詢最大的區(qū)別是,短輪詢?nèi)シ斩瞬樵兊臅r候奥洼,不管服務端有沒有變化巷疼,服務器就立即返回結(jié)果了。而長輪詢則不是灵奖,在長輪詢中嚼沿,服務器如果檢測到庫存量沒有變化的話,將會把當前請求掛起一段時間(這個時間也叫作超時時間瓷患,一般是幾十秒)骡尽。在這個時間里,服務器會去檢測庫存量有沒有變化擅编,檢測到變化就立即返回攀细,否則就一直等到超時為止,這就是區(qū)別爱态。
(實際開發(fā)中不會使用長短輪詢來做這種需求谭贪,這里僅僅是為了說明兩者區(qū)別而做的一個例子。)
長輪詢曾被 Facebook 早起版本采納锦担,示意圖如下:
HTML5 WebSocket: 雙向
參考: What are Long-Polling, Websockets, Server-Sent Events (SSE) and Comet?
我們可以看到俭识,發(fā)展歷史是這樣:從長短輪詢到長連接,使用 WebSocket 來替代 HTTP洞渔。
其中長短輪詢與長短連接的區(qū)別主要有:
- 概念范疇不同:長短輪詢是應用層概念套媚、長短連接是傳輸層概念
- 協(xié)商方式不同:一個 TCP 連接是否為長連接,是通過設置 HTTP 的 Connection Header 來決定的磁椒,而且是需要兩邊都設置才有效堤瘤。而一種輪詢方式是否為長輪詢,是根據(jù)服務端的處理方式來決定的衷快,與客戶端沒有關(guān)系宙橱。
- 實現(xiàn)方式不同:連接的長短是通過協(xié)議來規(guī)定和實現(xiàn)的姨俩。而輪詢的長短蘸拔,是服務器通過編程的方式手動掛起請求來實現(xiàn)的师郑。
在移動端上長連接是趨勢。
其最大的特點是節(jié)省 Header调窍。
輪詢與 WebSocket 所花費的Header流量對比:
讓我們來作一個測試:
假設 Header 是871字節(jié)宝冕,
我們以相同的頻率 10W/s 去做網(wǎng)絡請求, 對比下輪詢與 WebSocket 所花費的 Header 流量:
Header 包括請求和響應頭信息邓萨。
出于兼容性考慮地梨,一般建立 WebSocket 連接也采用 HTTP 請求的方式,那么從這個角度講:無論請求如何頻繁缔恳,都只需要一個 Header宝剖。
并且 Websocket 的數(shù)據(jù)傳輸是 frame 形式傳輸?shù)模瑤瑐鬏敻痈咝干酰瑢Ρ容喸兊?個 Header万细,這里只有一個 Header 和一個 frame。
而 Websocket 的frame 僅僅用2個字節(jié)就代替了輪詢的871字節(jié)纸泄!
相同的每秒客戶端輪詢的次數(shù)赖钞,當次數(shù)高達 10W/s 的高頻率次數(shù)的時候,Polling 輪詢需要消耗665Mbps聘裁,而 WebSocket 僅僅只花費了1.526Mbps雪营,將近435倍!衡便!
數(shù)據(jù)參考:
下面探討下長連接實現(xiàn)方式里的協(xié)議選擇:
大家都在使用什么技術(shù)
最近做了兩個 IM 相關(guān)的問卷献起,累計產(chǎn)生了900多條的投票數(shù)據(jù):
注:本次投票是發(fā)布在微博@iOS程序犭袁 镣陕,鑒于微博關(guān)注機制征唬,本數(shù)據(jù)只能反映出 IM 技術(shù)在 iOS 領(lǐng)域的使用情況,并不能反映出整個IT行業(yè)的情況茁彭。
下文會對這個投票結(jié)果進行下分析总寒。
投票結(jié)果 《你項目中使用什么協(xié)議實現(xiàn)了 IM 即時通訊》
協(xié)議如何選擇?
IM 協(xié)議選擇原則一般是:易于拓展理肺,方便覆蓋各種業(yè)務邏輯摄闸,同時又比較節(jié)約流量。后一點的需求在移動端 IM 上尤其重要妹萨。常見的協(xié)議有:XMPP年枕、SIP、MQTT乎完、私有協(xié)議熏兄。
我們這里只關(guān)注前三名,
名稱 | 優(yōu)點 | 缺點 |
---|---|---|
XMPP | 優(yōu)點:協(xié)議開源,可拓展性強摩桶,在各個端(包括服務器)有各種語言的實現(xiàn)桥状,開發(fā)者接入方便; | 缺點:缺點也是不少硝清,XML表現(xiàn)力弱辅斟、有太多冗余信息、流量大芦拿,實際使用時有大量天坑士飒。 |
MQTT | 優(yōu)點:協(xié)議簡單,流量少蔗崎;訂閱+推送模式酵幕,非常適合Uber、滴滴的小車軌跡的移動缓苛。 | 缺點:它并不是一個專門為 IM 設計的協(xié)議裙盾,多使用于推送。IM 情景要復雜得多他嫡,pub番官、sub,比如:加入對話钢属、創(chuàng)建對話等等事件徘熔。 |
私有協(xié)議 | 市面上幾乎所有主流IM APP都是是使用私有協(xié)議,一個被良好設計的私有協(xié)議優(yōu)點非常明顯淆党。優(yōu)點:高效酷师,節(jié)約流量(一般使用二進制協(xié)議),安全性高染乌,難以破解唧席; | 缺點:在開發(fā)初期沒有現(xiàn)有樣列可以參考味悄,對于設計者的要求比較高顺献。 |
一個好的協(xié)議需要滿足如下條件:高效承绸,簡潔,可讀性好勒庄,節(jié)約流量串前,易于拓展,同時又能夠匹配當前團隊的技術(shù)堆棧实蔽〉茨耄基于如上原則,我們可以得出: 如果團隊小局装,團隊技術(shù)在 IM 上積累不夠可以考慮使用 XMPP 或者 MQTT+HTTP 短連接的實現(xiàn)坛吁。反之可以考慮自己設計和實現(xiàn)私有協(xié)議劳殖,這里建議團隊有計劃地遷移到私有協(xié)議上。
這里特別提一下排名第二的 WebSocket 拨脉,區(qū)別于上面的聊天協(xié)議哆姻,這是一個傳輸通訊協(xié)議,那為什么會有這么多人在即時通訊領(lǐng)域運用了這一協(xié)議女坑?除了上文說的長連接特性外填具,這個協(xié)議 web 原生支持统舀,有很多第三方語言實現(xiàn)匆骗,可以搭配 XMPP、MQTT 等多種聊天協(xié)議進行使用誉简,被廣泛地應用于即時通訊領(lǐng)碉就。
社交場景
最大的特點在于:模式成熟,界面類似闷串。
我們專門為社交場景開發(fā)的開源組件:ChatKit-OC瓮钥,star數(shù),1000+烹吵。
ChatKit-OC 在協(xié)議選擇上使用的是 WebSocket 搭配私有聊天協(xié)議的方式碉熄,在數(shù)據(jù)傳輸上選擇的是 Protobuf 搭配 JSON 的方式。
項目地址:ChatKit-OC
下文會專門介紹下技術(shù)實現(xiàn)細節(jié)肋拔。
直播場景
一個演示如何為直播集成 IM 的開源直播 Demo:
項目地址:LiveKit-iOS
(這個庫锈津,我最近也在優(yōu)化,打算做成 Lib凉蜂,支持下 CocoaPods 琼梆。希望能幫助大家快速集成直播模塊。有興趣的也歡迎參與進來提 PR)
LiveKit 相較社交場景的特點:
- 無人數(shù)限制的聊天室
- 自定義消息
- 打賞機制的服務端配合
有人可能有這樣的疑問:
(叫我Elon(讀:一龍)就好了)
那么可以看下 Demo 的實現(xiàn):我們可以看到里面的彈幕窿吩、禮物茎杂、點贊出心這些都是 IM 系統(tǒng)里的自定義消息。
數(shù)據(jù)自動更新場景
- 打車應用場景(Uber纫雁、滴滴等 APP 首頁的移動小車)
- 朋友圈狀態(tài)的實施更新煌往,朋友圈自己發(fā)送的消息無需刷新,自動更新
這些場景比聊天要簡單許多轧邪,僅僅涉及到監(jiān)聽對象的訂閱携冤、取消訂閱。
正如上文所提到的闲勺,使用 MQTT 實現(xiàn)最為經(jīng)濟曾棕。用社交類、直播類的思路來做菜循,也可以實現(xiàn)翘地,但略顯冗余。
電梯場景(假在線狀態(tài)處理)
iOS端的假在線的狀態(tài),有兩種方案:
- 雙向ping pong機制
- iOS端只走APNs
雙向 ping-pong 機制:
Message 在發(fā)送后衙耕,在服務端維護一個表昧穿,一段時間內(nèi),比如15秒內(nèi)沒有收到 ack橙喘,就認為應用處于離線狀態(tài)时鸵,先將用戶踢下線,然后轉(zhuǎn)而進行推送厅瞎。這里如果出現(xiàn)饰潜,重復推送,客戶端要負責去重和簸。將 Message 消息相當于服務端發(fā)送的 Ping 消息彭雾,APP 的 ack 作為 pong。
使用 APNs 來作聊天
優(yōu)缺點:
優(yōu)點:
- 解決了锁保,iOS端假在線的問題薯酝。
缺點:(APNs的缺點)
- 無法保證消息的及時性。
- 讓服務端負載過重
APNs不保證消息的到達率爽柒,消息會被折疊:
你可能見過這種推送消息:
這中間發(fā)生了什么吴菠?
當 APNs 向你發(fā)送了4條推送,但是你的設備網(wǎng)絡狀況不好浩村,在 APNs 那里下線了做葵,這時 APNs 到你的手機的鏈路上有4條任務堆積,APNs 的處理方式是穴亏,只保留最后一條消息推送給你蜂挪,然后告知你推送數(shù)。那么其他三條消息呢嗓化?會被APNs丟棄棠涮。
有一些 App 的 IM 功能沒有維持長連接,是完全通過推送來實現(xiàn)的刺覆,通常情況下严肪,這些 App 也已經(jīng)考慮到了這種丟推送的情況,這些 App 的做法都是谦屑,每次收到推送之后驳糯,然后向自己的服務器查詢當前用戶的未讀消息。但是 APNs 也同樣無法保證這四條推送能至少有一條到達你的 App氢橙。
為什么這么設計酝枢?APNs的存儲-轉(zhuǎn)發(fā)能力太弱,大量的消息存儲和轉(zhuǎn)發(fā)將消耗 Apple 服務器的資源悍手,可能是出于存儲成本考慮帘睦,也可能是因為 Apple 轉(zhuǎn)發(fā)能力太弱袍患。總之結(jié)果就是 APNs 從來不保證消息的達到率竣付。并且設備上線之后也不會向服務器上傳信息诡延。
現(xiàn)在我們可以保證消息一定能推送到 APNs 那里,但是 APNs 不保證幫我們把消息投遞給用戶古胆。
即使搭配了這樣的策略:每次收到推送就拉歷史記錄的消息肆良,一旦消息被 APNs 丟棄,這條消息可能會在幾天之后受到了新推送后才被查詢到逸绎。
讓服務端負載過重:
APNs 的實現(xiàn)原理決定了:必須每次收到消息后惹恃,拉取歷史消息。這意味著你無法控制 APP 請求服務端的頻率桶良,同一時間十萬座舍、百萬的請求量都是可能的沮翔,這帶來的負載以及風險陨帆,有時甚至會比輪詢還要大。
結(jié)論:如果面向的目標用戶對消息的及時性并不敏感采蚀,可以采用這種方案疲牵。比如社交場景。(對消息較為敏感的APP則并不適合榆鼠,比如:專門為情侶間使用的APP纲爸。。妆够。)
技術(shù)實現(xiàn)細節(jié)
基于 WebSocket 的 IM 系統(tǒng)
WebSocket簡介
WebSocket 是 HTML5 開始提供的一種瀏覽器與服務器間進行全雙工通訊的網(wǎng)絡技術(shù)识啦。 WebSocket 通信協(xié)定于2011年被 IETF 定為標準 RFC 6455,WebSocket API 被 W3C 定為標準神妹。
在 WebSocket API 中颓哮,瀏覽器和服務器只需要要做一個握手的動作,然后鸵荠,瀏覽器和服務器之間就形成了一條快速通道冕茅。兩者之間就直接可以數(shù)據(jù)互相傳送。
只從 RFC 發(fā)布的時間看來蛹找,WebSocket要晚很多姨伤,HTTP 1.1是1999年,WebSocket 則是12年之后了庸疾。WebSocket 協(xié)議的開篇就說乍楚,本協(xié)議的目的是為了解決基于瀏覽器的程序需要拉取資源時必須發(fā)起多個HTTP請求和長時間的輪訓的問題而創(chuàng)建的〗齑龋可以達到支持 iOS徒溪,Android凌箕,Web 三端同步的特性。
更多
技術(shù)實現(xiàn)細節(jié)的部分較長词渤,單獨成篇牵舱。: 《技術(shù)實現(xiàn)細節(jié)》
下面是文章的第二部分:
性能調(diào)優(yōu) -- 針對移動網(wǎng)絡特點的性能調(diào)優(yōu)
極簡協(xié)議,傳輸協(xié)議 Protobuf
目錄如下:
- 極簡協(xié)議缺虐,傳輸協(xié)議 Protobuf
- 在安全上做了哪些事情芜壁?
- 防止 DNS 污染
- 賬戶安全
- 重連機制
- 使用 HTTP/2 減少不必要的網(wǎng)絡連接
- 設置合理的超時時間
- 圖片視頻等文件上傳
- 使用緩存:基于 Hash 的本地緩存校驗
首先讓我們來看下:
IM 即時通訊中你會選用什么數(shù)據(jù)傳輸格式?
之前做的調(diào)研數(shù)據(jù)如下:
《IM 即時通訊中你會選用什么數(shù)據(jù)傳輸格式高氮?》
注:本次投票是發(fā)布在微博@iOS程序犭袁 慧妄,鑒于微博關(guān)注機制,本數(shù)據(jù)只能反映出 IM 技術(shù)在 iOS 領(lǐng)域的使用情況剪芍,并不能反映出整個IT行業(yè)的情況塞淹。
排名前三的分別的JSON 、ProtocolBuffer罪裹、XML饱普;
這里重點推薦下 ProtocolBuffer:
該協(xié)議已經(jīng)在業(yè)內(nèi)有很多應用,并且效果顯著:
使用 ProtocolBuffer 減少 Payload
- 滴滴打車40%状共;
- 攜程之前分享過套耕,說是采用新的Protocol Buffer數(shù)據(jù)格式+Gzip壓縮后的Payload大小降低了15%-45%。數(shù)據(jù)序列化耗時下降了80%-90%峡继。
采用高效安全的私有協(xié)議冯袍,支持長連接的復用,穩(wěn)定省電省流量
- 【高效】提高網(wǎng)絡請求成功率碾牌,消息體越大康愤,失敗幾率隨之增加。
- 【省流量】流量消耗極少舶吗,省流量征冷。一條消息數(shù)據(jù)用Protobuf序列化后的大小是 JSON 的1/10、XML格式的1/20裤翩、是二進制序列化的1/10资盅。同 XML 相比, Protobuf 性能優(yōu)勢明顯踊赠。它以高效的二進制方式存儲呵扛,比 XML 小 3 到 10 倍,快 20 到 100 倍筐带。
- 【省電】省電
- 【高效心跳包】同時心跳包協(xié)議對IM的電量和流量影響很大今穿,對心跳包協(xié)議上進行了極簡設計:僅 1 Byte 。
- 【易于使用】開發(fā)人員通過按照一定的語法定義結(jié)構(gòu)化的消息格式伦籍,然后送給命令行工具蓝晒,工具將自動生成相關(guān)的類腮出,可以支持java、c++芝薇、python胚嘲、Objective-C等語言環(huán)境。通過將這些類包含在項目中洛二,可以很輕松的調(diào)用相關(guān)方法來完成業(yè)務消息的序列化與反序列化工作馋劈。語言支持:原生支持c++、java晾嘶、python妓雾、Objective-C等多達10余種語言。 2015-08-27 Protocol Buffers v3.0.0-beta-1中發(fā)布了Objective-C(Alpha)版本垒迂, 2016-07-28 3.0 Protocol Buffers v3.0.0正式版發(fā)布械姻,正式支持 Objective-C。
- 【可靠】微信和手機 QQ 這樣的主流 IM 應用也早已在使用它(采用的是改造過的Protobuf協(xié)議)
如何測試驗證 Protobuf 的高性能机断?
對數(shù)據(jù)分別操作100次楷拳,1000次,10000次和100000次進行了測試毫缆,
縱坐標是完成時間唯竹,單位是毫秒乐导,
反序列化 | 序列化 | 字節(jié)長度 |
---|---|---|
數(shù)據(jù)來自:項目 thrift-protobuf-compare,測試項為 Total Time物臂,也就是 指一個對象操作的整個時間旺拉,包括創(chuàng)建對象,將對象序列化為內(nèi)存中的字節(jié)序列棵磷,然后再反序列化的整個過程蛾狗。從測試結(jié)果可以看到 Protobuf 的成績很好.
缺點:
可能會造成 APP 的包體積增大,通過 Google 提供的腳本生成的 Model仪媒,會非吵磷溃“龐大”,Model 一多算吩,包體積也就會跟著變大留凭。
如果 Model 過多,可能導致 APP 打包后的體積驟增偎巢,但 IM 服務所使用的 Model 非常少蔼夜,比如在 ChatKit-OC 中只用到了一個 Protobuf 的 Model:Message對象,對包體積的影響微乎其微压昼。
在使用過程中要合理地權(quán)衡包體積以及傳輸效率的問題求冷,據(jù)說去哪兒網(wǎng)瘤运,就曾經(jīng)為了減少包體積,進而減少了 Protobuf 的使用匠题。
在安全上需要做哪些事情拯坟?
防止 DNS 污染
文章較長,單獨成篇韭山。: 《防 DNS 污染方案.md》
賬戶安全
IM 服務賬號密碼一旦泄露似谁,危害更加嚴峻。尤其是對于消息可以漫游的類型掠哥。比如:
介紹下我們是如何做到巩踏,即使是我們的服務器被攻破,你的用戶系統(tǒng)依然不會受到影響:
- 帳號安全:
無侵入的權(quán)限控制:
與用戶的用戶帳號體系完全隔離续搀,只需要提供一個ID就可以通信塞琼,接入方可以對該 ID 進行 MD5 加密后再進行傳輸和存儲,保證開發(fā)者用戶數(shù)據(jù)的私密性及安全禁舷。
- 簽名機制
對關(guān)鍵操作彪杉,支持第三方服務器鑒權(quán),保護你的信息安全牵咙。
- 單點登錄
讓 APP 支持單點登錄派近,能有限減少盜號造成的安全問題。在 ChatKit-OC 中洁桌,我們就默認開啟了單點登錄功能渴丸,以此來提升 APP 的安全性。
重連機制
- 精簡心跳包另凌,保證一個心跳包大小在10字節(jié)之內(nèi)谱轨;
- 減少心跳次數(shù):心跳包只在空閑時發(fā)送;從收到的最后一個指令包進行心跳包周期計時而不是固定時間吠谢。
- 重連冷卻
2的指數(shù)級增長2土童、4、8工坊,消息往來也算作心跳献汗。類似于 iPhone 密碼的 錯誤機制,冷卻單位是5分鐘王污,依次是5分鐘后罢吃、10分鐘后、15分鐘后玉掸,10次輸錯刃麸,清除數(shù)據(jù)。
當然司浪,這樣靈活的策略也同樣決定了泊业,只能在 APP 層進行心跳ping把沼。
這里有必要提一下重連機制的必要性,我們知道 TCP 也有庇跛牛活機制饮睬,但這個與我們在這里討論的“心跳保活”機制是有區(qū)別的篮奄。
TCP 崩Τ睿活(TCP KeepAlive 機制)和心跳保活區(qū)別:
TCP笨呷矗活 | 心跳敝绯螅活 |
---|---|
在定時時間到后,一般是 7200 s夸赫,發(fā)送相應的 KeepAlive 探針菩帝。,失敗后重試 10 次茬腿,每次超時時間 75 s呼奢。(詳情請參見《TCP/IP詳解》中第23章) | 通常可以設置為3-5分鐘發(fā)出 Ping |
檢測連接的死活(對應于下圖中的1) | 檢測通訊雙方的存活狀態(tài)(對應于下圖中的2) |
鼻衅剑活握础,究竟保的是誰?
比如:考慮一種情況悴品,某臺服務器因為某些原因?qū)е仑撦d超高禀综,CPU 100%,無法響應任何業(yè)務請求他匪,但是使用 TCP 探針則仍舊能夠確定連接狀態(tài)菇存,這就是典型的連接活著但業(yè)務提供方已死的狀態(tài),對客戶端而言邦蜜,這時的最好選擇就是斷線后重新連接其他服務器,而不是一直認為當前服務器是可用狀態(tài)亥至,一直向當前服務器發(fā)送些必然會失敗的請求悼沈。
使用 HTTP/2 減少不必要的網(wǎng)絡連接
大多數(shù)的移動網(wǎng)絡(3G)并不允許一個給定 IP 地址超過兩個的并發(fā) HTTP 請求,既當你有兩個針對同一個地址的連接時姐扮,再發(fā)起的第三個連接總是會超時絮供。而2G網(wǎng)絡下這個限定為1個。同一時間發(fā)起過多的網(wǎng)絡請求不僅不會起到加速的效果茶敏,反而有副作用壤靶。
另一方面,由于網(wǎng)絡連接很是費時惊搏,保持和共享某一條連接就是一個不錯的選擇:比如短時間內(nèi)多次的HTTP請求贮乳。
使用 HTTP/2 就可以達到這樣的目的忧换。
HTTP/2 是 HTTP 協(xié)議發(fā)布后的首個更新,于2015年2月17日被批準向拆。它采用了一系列優(yōu)化技術(shù)來整體提升 HTTP 協(xié)議的傳輸性能亚茬,如異步連接復用、頭壓縮等等浓恳,可謂是當前互聯(lián)網(wǎng)應用開發(fā)中刹缝,網(wǎng)絡層次架構(gòu)優(yōu)化的首選方案之一。
HTTP/2 也以高復用著稱颈将,而且如果我們要使用 HTTP/2梢夯,那么在網(wǎng)絡庫的選擇上必然要使用 NSURLSession。所以 AFN2.x 也需要升級到AFN3.x.
設置合理的超時時間
過短的超時容易導致連接超時的事情頻頻發(fā)生晴圾,甚至一直無法連接厨疙,而過長的超時則會帶來等待時間過長,體驗差的問題疑务。就目前來看沾凄,對于普通的TCP連接30秒是個不錯的超時值,而Http請求可以按照重要性和當前網(wǎng)絡情況動態(tài)調(diào)整超時知允,盡量將超時控制在一個合理的數(shù)值內(nèi)撒蟀,以提高單位時間內(nèi)網(wǎng)絡的利用率。
圖片視頻等文件上傳
圖片格式優(yōu)化在業(yè)界已有成熟的方案温鸽,例如 Facebook 使用的 WebP 圖片格式保屯,已經(jīng)被國內(nèi)眾多 App 使用。
分片上傳涤垫、斷點續(xù)傳姑尺、秒傳技術(shù)、
- 文件分塊上傳:因為移動網(wǎng)絡丟包嚴重蝠猬,將文件分塊上傳可以使得一個分組包含合理數(shù)量的TCP包切蟋,使得重試概率下降,重試代價變小榆芦,更容易上傳到服務器柄粹;
- 提供文件秒傳的方式:服務器根據(jù)MD5、SHA進行文件去重匆绣;
- 支持斷點續(xù)傳驻右。
- 上傳失敗,合理的重連崎淳,比如3次堪夭。
使用緩存:基于 Hash 的本地緩存校驗
微信是不用考慮消息同步問題,因為微信是不存儲歷史記錄的,卸載重裝消息記錄就會丟失森爽。
所以我們可以采用一個類似 E-Tag恨豁、Last-Modified 的本地消息緩存校驗機制,具體做法就是拗秘,當我們想加載最近10條的聊天記錄時圣絮,先將本地緩存的最近10條做一個 hash 值,將 hash 值發(fā)送給服務端雕旨,服務端將服務端的最近十條做一個 hash 扮匠,如果一致就返回304。最理想的情況是服務端一直返回304凡涩,一直加載本地記錄棒搜。這樣做的好處:
- 消息同步
- 節(jié)省流量
IM系列文章
IM 系列文章分為下面這幾篇:
- 《IM 即時通訊技術(shù)在多應用場景下的技術(shù)實現(xiàn),以及性能調(diào)優(yōu)(iOS視角)》 (本文)
- 《技術(shù)實現(xiàn)細節(jié)》
- 《有一種 Block 叫 Callback活箕,有一種 Callback 做 CompletionHandler》
- 《防 DNS 污染方案》
本文是第一篇力麸。
Posted by 微博@iOS程序犭袁
原創(chuàng)文章,版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0