亚洲农村老熟妇肥BBBB_无码人妻精品一区二区蜜桃色_精品亚洲AⅤ无码午夜在线观看_中文字幕熟妇人妻在线视频_囯产色无码精品视频免费

當前位置: 首頁 > 軍事新聞 >

移動IM開發(fā)那點事

時間:2020-07-15 18:08來源:網(wǎng)絡(luò)整理 瀏覽:
移動IM開發(fā)技術(shù)選型(包括通訊方式, 網(wǎng)絡(luò)連接方式, 協(xié)議選擇) 和常見問題匯總。1.通訊方式選擇IM 通訊方式無非兩種選擇: 設(shè)備直連 (

移動IM開發(fā)技術(shù)選型(包括通訊方式, 網(wǎng)絡(luò)連接方式, 協(xié)議選擇) 和常見問題匯總。


移動IM開發(fā)那點事


1.通訊方式選擇

IM 通訊方式無非兩種選擇: 設(shè)備直連 (P2P) 和通過服務(wù)器中轉(zhuǎn)。

1.1 P2P

P2P 多見于局域網(wǎng)內(nèi)聊天工具,典型的應(yīng)用有: 飛鴿傳書,飛秋等。這類軟件在啟動后一般做兩件事情

進行 UDP 廣播: 發(fā)送自己信息和接受同局域網(wǎng)內(nèi)其他端信息開啟 TCP 監(jiān)聽: 等待其他端進行連接

詳細的流程可以參考 飛鴿傳書源碼。但是這種方式有各種限制和不便: 一方面它只適合在線的點對點消息傳輸,對離線,群組等業(yè)務(wù)支持不夠。另一方面由于 NAT 的存在,使得不同局域網(wǎng)內(nèi)機器互聯(lián)難度大大上升,在某些網(wǎng)絡(luò)類型(對稱 NAT) 下無法建立連接。

1.2 服務(wù)器中轉(zhuǎn)

幾乎所有互聯(lián)網(wǎng) IM 產(chǎn)品都采用服務(wù)器中轉(zhuǎn)這種方式進行消息傳輸,相對于 P2P 的方式,它有如下的優(yōu)點:

能夠支持更多 P2P 無法支持或支持不好的業(yè)務(wù),如離線消息,群組,聊天室服務(wù)方便業(yè)務(wù)邏輯的拓展和新舊版本的兼容

當然它也有自己的問題: 服務(wù)器架構(gòu)復(fù)雜,并發(fā)要求高。

2.網(wǎng)絡(luò)連接方式

IM 主流網(wǎng)絡(luò)連接方式有兩種:

基于 TCP 的長連接基于 HTTP 短連接 PULL 的方式

后者常見于 WEB IM 系統(tǒng)(當然現(xiàn)在很多 WEB IM 都是基于 WebSocket 實現(xiàn)),它的優(yōu)點是實現(xiàn)簡單,方便開發(fā)上手,問題是流量大,服務(wù)器負載較大,消息及時性無法很好地保證,對大規(guī)模的用戶量支持不夠,比較適合小型的 IM 系統(tǒng), 如小網(wǎng)站的客戶系統(tǒng)。

基于 TCP 長連接則能夠更好地支持大批量用戶,問題是客戶端和服務(wù)器的實現(xiàn)比較復(fù)雜。當然也還有一些變種,如下行使用 MQTT 進行服務(wù)器通知 / 消息的下發(fā),上行使用 HTTP 短連接進行指令和消息的上傳。這種方式能夠保證下行消息 / 指令的及時性,但是在弱網(wǎng)絡(luò)下上行慢的問題還是比較嚴重。早期的來往就是基于這種方式。

3.協(xié)議選擇

IM 協(xié)議選擇原則一般是: 易于拓展,方便覆蓋各種業(yè)務(wù)邏輯,同時又比較節(jié)約流量。后一點的需求在移動端 IM 上尤其重要。

常見的協(xié)議有:

XMPPSIPMQTT私有協(xié)議

XMPP 協(xié)議的優(yōu)點在于: 協(xié)議開源,可拓展性強,在各個端 (包括服務(wù)器) 有各種語言的實現(xiàn),開發(fā)者接入方便。但是缺點也是不少: XML 有太多冗余信息,流量大,實際使用時有大量天坑。

SIP 協(xié)議多用于 VOIP 相關(guān)的模塊,是一種文本協(xié)議,由于我并沒有實際用過,所以不做評論,但從它是文本協(xié)議這一點幾乎可以斷定它的流量不會小。

MQTT 的優(yōu)點是協(xié)議簡單,流量少,但是它并不是一個專門為 IM 設(shè)計的協(xié)議,多使用于推送。

而市面上幾乎所有主流 IM APP 都是是使用私有協(xié)議,一個被良好設(shè)計的私有協(xié)議一般有如下優(yōu)點: 高效,節(jié)約流量(一般使用二進制協(xié)議),安全性高,難以破解。缺點則是在開發(fā)初期沒有現(xiàn)有樣列可以參考,對于設(shè)計者的要求比較高。

一個好的協(xié)議需要滿足如下條件: 高效,簡潔,可讀性好,節(jié)約流量,易于拓展,同時又能夠匹配當前團隊的技術(shù)堆棧?;谌缟显瓌t,我們可以推出: 如果團隊小,團隊技術(shù)在 IM 上積累不夠可以考慮使用 XMPP 或者 MQTT+HTTP 短連接的實現(xiàn)。反之可以考慮自己設(shè)計和實現(xiàn)私有協(xié)議。

4.私有協(xié)議的設(shè)計

4.1序列化選擇

移動互聯(lián)網(wǎng)相對于有線網(wǎng)絡(luò)最大特點是: 帶寬低,延遲高,丟包率高和穩(wěn)定性差,流量費用高。所以在私有協(xié)議的序列化上一般使用二進制協(xié)議,而不是文本協(xié)議。常見的二進制序列化庫有 protobufMessagePack,當然你也可以自己實現(xiàn)自己的二進制協(xié)議序列化和反序列的過程,比如蘑菇街的TeamTalk。但是前面二者無論是可拓展性還是可讀性都完爆 TeamTalk(TeamTalk 連 Variant 都不支持,一個 int 傳輸時固定占用 4 個字節(jié)),所以大部分情況下還是不推薦自己去實現(xiàn)二進制協(xié)議的序列化和反序列化過程。

4.2 協(xié)議格式設(shè)計

基于 TCP 的應(yīng)用層協(xié)議一般都分為包頭和包體(如 HTTP),IM 協(xié)議也不例外。包頭一般用于表示每個請求 / 反饋的公共部分,如包長,請求類型,返回碼等。 而包頭則填充不同請求 / 反饋對應(yīng)的信息。

一個最簡單的包頭可以定義為

struct PackHeader
{
int32_t length_; // 包長度
int32_t serial_; // 包序列號
int32_t command_; // 包請求類型
int32_t code_; // 返回碼
};

以心跳包為例,假設(shè)當前的 serial 為 1,心跳包的 command 為 10,那么使用 MessagePack 做序列化時: length=4,serial=1,command=10,code=0,每個字段各占一個字節(jié),包體為空,僅需要 4 個字節(jié)。

當然這是最簡單的一個例子,面對真正的業(yè)務(wù)邏輯時,包體里面會需要塞入更多地信息,這個需要開發(fā)根據(jù)自己的業(yè)務(wù)邏輯總結(jié)公共部分, 如為了兼容加入的協(xié)議版本號, 為了負載均衡加入的模塊 id 等。

5.其他問題

上面就是一個 IM 系統(tǒng)大致的選型過程: 通訊方式,連接方式,協(xié)議選擇,協(xié)議設(shè)計。但是實際開發(fā)過程中還有大量的問題需要處理。

5.1協(xié)議加密

為了保證協(xié)議不容易被破解,市面上幾乎所有主流 IM 都會對協(xié)議進行加密傳輸。常見的流程和 HTTPS 加密相似: 建立連接后,客戶端和服務(wù)器進行進行協(xié)商,最終客戶端獲得一個當前 Session 秘鑰,后續(xù)的數(shù)據(jù)傳輸都通過這個秘鑰進行加解密。一般出于效率的考慮都會采用流式加密,如 RC4。而前期協(xié)商過程則推薦使用 RSA 等非對稱加密以增加破解難度。

5.2快速連接(登錄)

對 iOS APP 而言,因為沒有真后臺的存在,APP 每次啟動基本都需要一次重連登錄(短時間內(nèi)切換除外),所以如何快速重連重登就非常重要。常見的優(yōu)化思路如下:

本地緩存服務(wù)器 IP 并定期刷新。移動網(wǎng)絡(luò)調(diào)優(yōu)可以參考《iOS 移動網(wǎng)絡(luò)調(diào)優(yōu)那些事》。合并部分請求。如加密和登錄操作可以合并為同一個操作,這樣就可以減少一次不必要的網(wǎng)絡(luò)請求來回的時間。簡化登錄后的同步請求,部分同步請求可以推遲到 UI 操作時進行,如群成員信息刷新。

5.3連接保持

一般 APP 實現(xiàn)連接保持的方式無非是采用應(yīng)用層的心跳,通過心跳包的超時和其他條件 (網(wǎng)絡(luò)切換) 來執(zhí)行重連操作。那么問題來了: 為什么要使用應(yīng)用層心跳和如何設(shè)計應(yīng)用層心跳。

眾所周知 TCP 協(xié)議是有 KEEPALIVE 這個設(shè)置選項,設(shè)置為 KEEPALIVE 后,客戶端每隔 N 秒 (默認是 7200s) 會向服務(wù)器發(fā)送一個發(fā)送心跳包。但實際操作中我們更多的時是使用應(yīng)用層心跳。原因如下:

KEEPALIVE 對服務(wù)器負載壓力比較大(服務(wù)器大大是這么說的…)socks 代理對 KEEPALIVE 并不支持部分復(fù)雜情況下 KEEPALIVE 會失效,如路由器掛掉,網(wǎng)線 (移動端沒有網(wǎng)線…) 直接被拔除

移動端在實際操作時為了節(jié)約流量和電量一般會在心跳包上做一些小優(yōu)化

精簡心跳包,保證一個心跳包大小在 10 字節(jié)之內(nèi)心跳包只在空閑時發(fā)送根據(jù) APP 前后臺狀態(tài)調(diào)整心跳包間隔 (主要是安卓)

5.4消息可達

在移動網(wǎng)絡(luò)下,丟包,網(wǎng)絡(luò)重連等情況非常之多,為了保證消息的可達,一般需要做消息回執(zhí)和重發(fā)機制。參考易信,每條消息會最多會有 3 次重發(fā),超時時間為 15 秒,同時在發(fā)送之前會檢測當前連接狀態(tài),如果當前連接并沒有正確建立,緩存消息且定時檢查(每隔 2 秒檢查一次,檢查 15 次)。所以一條消息在最差的情況下會有 2 分鐘左右的重試時間,以保證消息的可達。

因為重發(fā)的存在,接受端偶爾會收到重復(fù)消息,這種情況下就需要接收端進行去重。通用的做法是每條消息都帶上自己唯一的 message id(一般是 uuid)。

5.5文件上傳優(yōu)化

IM 消息 (包括 SNS 模塊) 內(nèi)包含大量的文件上傳的需求,如何優(yōu)化文件的上傳就成了一個比較大的主題。常見有下面這些優(yōu)化思路:

將上傳流程提前: 音頻提供邊錄邊傳。朋友圈的圖片進行預(yù)上傳,選擇圖片后用戶一般會進行文本輸入,在這段時間內(nèi)后臺就可以默默將選好的圖片進行上傳。提供閃電上傳的方式: 服務(wù)器根據(jù) MD5 進行文件去重。優(yōu)化和上傳服務(wù)器的連接(參考快速連接),提供連接重用的功能。文件分塊上傳: 因為移動網(wǎng)絡(luò)丟包嚴重,將文件分塊上傳可以使得一個分組包含合理數(shù)量的 TCP 包,使得重試概率下降,重試代價變小,更容易上傳到服務(wù)器。在分包的前提下支持上傳的 pipeline ,避免不必要的網(wǎng)絡(luò)等待時間。支持斷點續(xù)傳
推薦內(nèi)容