通訊方式選擇
im通訊方式無非兩種選擇:裝置直連(p2p)和通過伺服器中轉。
p2p
p2p多見於區域網內聊天工具,典型的應用有:飛鴿傳書,天網maze(***)等。這類軟體在啟動後一般做兩件事情
進行udp廣播:傳送自己資訊和接受同區域網內其他端資訊
開啟tcp監聽:等待其他端進行連線
伺服器中轉
幾乎所有網際網路im產品都採用伺服器中轉這種方式進行訊息傳輸,相對於p2p的方式,它有如下的優點:
當然它也有自己的問題:伺服器架構複雜,併發要求高。
網路連線方式
im主流網路連線方式有兩種:
後者常見於web im系統(當然現在很多web im都是基於websocket實現),它的優點是實現簡單,方便開發上手,問題是流量大,伺服器負載較大,訊息及時性無法很好地保證,對大規模的使用者量支援不夠,比較適合小型的im系統,如乙個小**的客戶系統。
基於tcp長連線則夠更好地支援大批量使用者,問題是客戶端和伺服器的實現比較複雜。當然也還有一些變種,如下行使用mqtt進行伺服器通知/訊息的下發,上行使用http短連線進行指令和訊息的上傳。這種方式能夠保證下行訊息/指令的及時性,但是在弱網路下上行慢的問題還是比較嚴重。早期的來往就是基於這種方式。
協議選擇
im協議選擇原則一般是:易於拓展,方便覆蓋各種業務邏輯,同時又比較節約流量。後一點的需求在移動端im上尤其重要。
常見的協議有:
xmpp協議的優點在於:協議開源,可拓展性強,在各個端(包括伺服器)有各種語言的實現,開發者接入方便。但是缺點也是不少:xml表現力弱,有太多冗餘資訊,流量大,實際使用時有大量天坑。
mqtt的優點是協議簡單,流量少,但是它並不是乙個專門為im設計的協議,多使用於推送。
乙個好的協議需要滿足如下條件:高效,簡潔,可讀性好,節約流量,易於拓展,同時又能夠匹配當前團隊的技術堆疊。基於如上原則,我們可以推出: 如果團隊小,團隊技術在im上積累不夠可以考慮使用xmpp或者mqtt+http短連線的實現。反之可以考慮自己設計和實現私有協議。
私有協議的設計
序列化選擇
移動網際網路相對於有線網路最大特點是:頻寬低,延遲高,丟包率高和穩定性差,流量費用高。所以在私有協議的序列化上一般使用二進位制協議,而不是文字協議。常見的二進位制序列化庫有protobuf和messagepack,當然你也可以自己實現自己的二進位制協議序列化和反序列的過程,比如蘑菇街的teamtalk。但是前面二者無論是可拓展性還是可讀性都完爆teamtalk(teamtalk連variant都不支援,乙個int傳輸時固定占用4個位元組),所以大部分情況下還是不推薦自己去實現二進位制協議的序列化和反序列化過程。
協議格式設計
基於tcp的應用層協議一般都分為包頭和包體(如http),im協議也不例外。包頭一般用於表示每個請求/反饋的公共部分,如包長,請求型別,返回碼等。 而包頭則填充不同請求/反饋對應的資訊。
乙個最簡單的包頭可以定義為
1
2
3
4
5
6
7
struct packheader
;
以心跳包為例,假設當前的serial為1,心跳包的command為10,那麼使用messagepack做序列化時:length=4,serial=1,command=10,code=0,每個欄位各佔乙個位元組,包體為空,僅需要4個位元組。
當然這是最簡單的乙個例子,面對真正的業務邏輯時,包體裡面會需要塞入更多地資訊,這個需要開發根據自己的業務邏輯總結公共部分,如為了相容加入的協議版本號,為了負載均衡加入的模組id等。
其他問題
上面就是乙個im系統大致的選型過程:通訊方式,連線方式,協議選擇,協議設計。但是實際開發過程中還有大量的問題需要處理。
協議加密
為了保證協議不容易被破解,市面上幾乎所有主流im都會對協議進行加密傳輸。常見的流程和https加密相似:建立連線後,客戶端和伺服器進行進行協商,最終客戶端獲得乙個當前sessino的秘鑰,後續的資料傳輸都通過這個秘鑰進行加解密。一般出於效率的考慮都會採用流式加密,如rc4。而前期協商過程則推薦使用aes等非對稱加密以增加破解難度。
快速連線(登入)連線保持眾所周知tcp協議是有keepalive這個設定選項,設定為keepalive後,客戶端每隔n秒(預設是7200s)會向伺服器傳送乙個傳送心跳包。但實際操作中我們更多的時是使用應用層心跳。原因如下:
移動端在實際操作時為了節約流量和電量一般會在心跳包上做一些小優化
訊息可達
在流動網路下,丟包,網路重連等情況非常之多,為了保證訊息的可達,一般需要做訊息回執和重發機制。參考易信,每條訊息會最多會有3次重發,超時時間為15秒,同時在傳送之前會檢測當前連線狀態,如果當前連線並沒有正確建立,快取訊息切定時檢查(每隔2秒檢查一次,檢查15次)。所以一條訊息在最差的情況下會有2分多的重試時間,以保證訊息的可達。
因為重發的存在,接受端偶爾會收到重複的兩條訊息,這種情況下就需要接收端進行去重。一般的做法是每條訊息都有自己唯一的message id(一般是uuid)。
檔案上傳優化
im訊息(包括sns模組)內包含大量的檔案上傳的需求,如何優化檔案的上傳就成了乙個比較大的主題。常見有下面這些優化思路:
移動IM開發指南1 如何進行技術選型
移動im開發指南2 心跳指令詳解 移動im開發指南3 如何優化登入模組 im通訊方式無非兩種選擇 裝置直連 p2p 和通過伺服器中轉 1.p2p p2p多見於區域網內聊天工具,典型的應用有 飛鴿傳書等。這類軟體在啟動後一般做兩件事情 2.伺服器中轉 幾乎所有網際網路im產品都採用伺服器中轉這種方式進...
開發那些事
記錄下想法。對於軟體開發,絕大多數情況下,乙個優秀的專案,離不開乙個優秀的團隊。軟體開發的流程會很大程度上決定開發的效率。很大一部分也和企業文化 團隊氣氛有關。我說下自己的體會。嚴謹的開發流程,詳細文件還有積極的溝通是至關重要的。1.專案管理工具。團隊需要乙個內部wiki或者專案管理工具開記錄工作報...
移動 IM 開發之心跳
什麼是心跳?在使用 tcp 長連線的im 服務設計中,往往都會涉及到心跳。心跳一般是指某端 絕大多數情況下是客戶端 每隔一定時間向對端傳送自定義指令,以判斷雙方是否存活,因其按照一定間隔傳送,類似於心跳,故被稱為心跳指令。為什麼要在應用層做心跳 那麼問題就隨之而來了 為什麼需要在應用層做心跳,難道 ...