即时通讯 IM 开发指南 1:如何进行技术选型
《移動(dòng)IM開(kāi)發(fā)指南》系列文章將會(huì)介紹一個(gè)IM APP的方方面面,包括技術(shù)選型、登陸優(yōu)化等。此外,本文作者會(huì)結(jié)合他在網(wǎng)易云信多年 iOS IM SDK 開(kāi)發(fā)的經(jīng)驗(yàn),深度分析實(shí)際開(kāi)發(fā)中的各種常見(jiàn)問(wèn)題。
### 通訊方式選擇
IM通訊方式無(wú)非兩種選擇:設(shè)備直連(P2P)和通過(guò)服務(wù)器中轉(zhuǎn)。
1、 P2P
P2P 多見(jiàn)于局域網(wǎng)內(nèi)聊天工具,典型的應(yīng)用有:飛鴿傳書(shū)等。這類(lèi)軟件在啟動(dòng)后一般做兩件事情:
- 進(jìn)行 UDP 廣播:發(fā)送自己信息和接受同局域網(wǎng)內(nèi)其他端信息
- 開(kāi)啟 TCP 監(jiān)聽(tīng):等待其他端進(jìn)行連接
詳細(xì)的流程可以參考飛鴿傳書(shū)源碼。但是這種方式在有種種限制和不便:一方面它只適合在線的點(diǎn)對(duì)點(diǎn)消息傳輸,對(duì)離線,群組等業(yè)務(wù)支持不夠。另一方面由于 NAT 的存在,使得不同局域網(wǎng)內(nèi)機(jī)器互聯(lián)難度大大上升,在某些網(wǎng)絡(luò)類(lèi)型(對(duì)稱(chēng) NAT)下無(wú)法建立連接。
2、 服務(wù)器中轉(zhuǎn)
幾乎所有互聯(lián)網(wǎng)IM產(chǎn)品都采用服務(wù)器中轉(zhuǎn)這種方式進(jìn)行消息傳輸,相對(duì)于P2P的方式,它有如下的優(yōu)點(diǎn):
- 能夠支持更多P2P無(wú)法支持或支持不好的業(yè)務(wù),如離線消息,群組,聊天室服務(wù)
- 方便業(yè)務(wù)邏輯的拓展和新舊版本的兼容
當(dāng)然它也有自己的問(wèn)題:服務(wù)器架構(gòu)復(fù)雜,并發(fā)要求高。
網(wǎng)絡(luò)連接方式
IM 主流網(wǎng)絡(luò)連接方式有兩種:
- 基于 TCP 的長(zhǎng)連接
- 基于 HTTP 短連接 PULL 的方式
后者常見(jiàn)于 Web IM 系統(tǒng)(當(dāng)然現(xiàn)在很多 Web IM 都是基于 WebSocket 實(shí)現(xiàn)),它的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,方便開(kāi)發(fā)上手,問(wèn)題是流量大,服務(wù)器負(fù)載較大,消息及時(shí)性無(wú)法很好地保證,對(duì)大規(guī)模的用戶量支持不夠,比較適合小型的 IM 系統(tǒng),如小網(wǎng)站的客戶系統(tǒng)。
基于 TCP 長(zhǎng)連接則能夠更好地支持大批量用戶,問(wèn)題是客戶端和服務(wù)器的實(shí)現(xiàn)比較復(fù)雜。當(dāng)然也還有一些變種,如下行使用 MQTT 進(jìn)行服務(wù)器通知/消息的下發(fā),上行使用 HTTP 短連接進(jìn)行指令和消息的上傳。這種方式能夠保證下行消息/指令的及時(shí)性,但是在弱網(wǎng)絡(luò)下上行慢的問(wèn)題還是比較嚴(yán)重。早期的來(lái)往就是基于這種方式。
協(xié)議選擇
IM 協(xié)議選擇原則一般是:易于拓展,方便覆蓋各種業(yè)務(wù)邏輯,同時(shí)又比較節(jié)約流量。后一點(diǎn)的需求在移動(dòng)端 IM 上尤其重要。
常見(jiàn)的協(xié)議有:XMPP;SIP;MQTT;私有協(xié)議。
- XMPP 協(xié)議的優(yōu)點(diǎn)在于:協(xié)議開(kāi)源,可拓展性強(qiáng),在各個(gè)端(包括服務(wù)器)有各種語(yǔ)言的實(shí)現(xiàn),開(kāi)發(fā)者接入方便。
但是缺點(diǎn)也是不少:XML 表現(xiàn)力弱,有太多冗余信息,流量大,實(shí)際使用時(shí)有大量天坑。
- SIP 協(xié)議多用于 VOIP 相關(guān)的模塊,是一種文本協(xié)議,由于我并沒(méi)有實(shí)際用過(guò),所以不做評(píng)論,但從它是文本協(xié)議這一點(diǎn)幾乎可以斷定它的流量不會(huì)小。
- MQTT 的優(yōu)點(diǎn)是協(xié)議簡(jiǎn)單,流量少,但是它并不是一個(gè)專(zhuān)門(mén)為 IM 設(shè)計(jì)的協(xié)議,多使用于推送。
- 市面上幾乎所有主流 IM APP 都是使用私有協(xié)議,一個(gè)被良好設(shè)計(jì)的私有協(xié)議一般有如下優(yōu)點(diǎn):高效,節(jié)約流量(一般使用二進(jìn)制協(xié)議),安全性高,難以破解。缺點(diǎn)則是在開(kāi)發(fā)初期沒(méi)有現(xiàn)有樣列可以參考,對(duì)于設(shè)計(jì)者的要求比較高。
一個(gè)好的協(xié)議需要滿足如下條件:高效,簡(jiǎn)潔,可讀性好,節(jié)約流量,易于拓展,同時(shí)又能夠匹配當(dāng)前團(tuán)隊(duì)的技術(shù)堆棧。基于如上原則,我們可以推出: 如果團(tuán)隊(duì)小,團(tuán)隊(duì)技術(shù)在 IM 上積累不夠可以考慮使用 XMPP 或者 MQTT+HTTP 短連接的實(shí)現(xiàn)。反之可以考慮自己設(shè)計(jì)和實(shí)現(xiàn)私有協(xié)議。
私有協(xié)議的設(shè)計(jì)
- 序列化選擇移動(dòng)互聯(lián)網(wǎng)相對(duì)于有線網(wǎng)絡(luò)最大特點(diǎn)是:帶寬低,延遲高,丟包率高和穩(wěn)定性差,流量費(fèi)用高。所以在私有協(xié)議的序列化上一般使用二進(jìn)制協(xié)議,而不是文本協(xié)議。常見(jiàn)的二進(jìn)制序列化庫(kù)有 protobuf 和 MessagePack,當(dāng)然你也可以自己實(shí)現(xiàn)自己的二進(jìn)制協(xié)議序列化和反序列的過(guò)程,比如蘑菇街的 TeamTalk。但是前面二者無(wú)論是可拓展性還是可讀性都完爆 TeamTalk(TeamTalk 連 Variant 都不支持,一個(gè) int 傳輸時(shí)固定占用 4 個(gè)字節(jié)),所以大部分情況下還是不推薦自己去實(shí)現(xiàn)二進(jìn)制協(xié)議的序列化和反序列化過(guò)程。
- 協(xié)議格式設(shè)計(jì)基于 TCP 的應(yīng)用層協(xié)議一般都分為包頭和包體(如 HTTP),IM 協(xié)議也不例外。包頭一般用于表示每個(gè)請(qǐng)求/反饋的公共部分,如包長(zhǎng),請(qǐng)求類(lèi)型,返回碼等。 而包頭則填充不同請(qǐng)求/反饋對(duì)應(yīng)的信息。
一個(gè)最簡(jiǎn)單的包頭可以定義為
以心跳包為例,假設(shè)當(dāng)前的 serial 為 1,心跳包的 command 為 10,那么使用 MessagePack 做序列化時(shí):length=4,serial=1,command=10,code=0,每個(gè)字段各占一個(gè)字節(jié),包體為空,僅需要 4 個(gè)字節(jié)。
當(dāng)然這是最簡(jiǎn)單的一個(gè)例子,面對(duì)真正的業(yè)務(wù)邏輯時(shí),包體里面會(huì)需要塞入更多地信息,這個(gè)需要開(kāi)發(fā)根據(jù)自己的業(yè)務(wù)邏輯總結(jié)公共部分,如為了兼容加入的協(xié)議版本號(hào),為了負(fù)載均衡加入的模塊 id 等。
上面就是 IM 系統(tǒng)大致的選型過(guò)程,包含了通訊方式,連接方式,協(xié)議選擇,協(xié)議設(shè)計(jì)。但是實(shí)際開(kāi)發(fā)過(guò)程中還有大量的問(wèn)題需要處理。《移動(dòng)IM開(kāi)發(fā)指南》系列文章第二篇將會(huì)為大家解答實(shí)際開(kāi)發(fā)中的常見(jiàn)問(wèn)題。
隨著即時(shí)通訊以及音頻處理和壓縮技術(shù)的不斷發(fā)展,效果更好、適用范圍更廣、性能更高的算法和新的技術(shù)必將不斷涌現(xiàn),如果你有好的技術(shù)或者分享,歡迎關(guān)注網(wǎng)易云信官方博客和 GitHub:
關(guān)注更多技術(shù)干貨內(nèi)容:網(wǎng)易云信博客歡迎關(guān)注網(wǎng)易云信 GitHub
歡迎關(guān)注網(wǎng)易云信官網(wǎng) 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)
總結(jié)
以上是生活随笔為你收集整理的即时通讯 IM 开发指南 1:如何进行技术选型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 简单的无线桥接技术-无线桥接技术有哪些
- 下一篇: c++primer plus 第11章