iOS高性能IM自研方案

一、開發IM的同學建議空暇時間多去(即時通訊)官網看看相關資料,便于自己能更好的優化自己的邏輯

二、通篇文章在 https://blog.csdn.net/weixin_43487250/article/details/123767010??有書面詳細形式總結

三、下方總結是IM選型從那些方面考慮和調研(備注:下方涉及到的項目和demo等可以聯系樓主索要demo或者項目源碼)

自研發IM /繼承第三方研發IM整套架構設計

1.第三方形式,根據app業務,是否設計國內外以及不同的收費標準主流有七牛云,阿里百川,騰訊云,網易,融云,環信等多家主流三方,個人傾向網易和融云。

原因:

網易比較快速集成,各網站資料較多,容易借鑒。但后續帶寬服務收費較高。

融云也容易集成,但是SDK自帶UI和不帶UI的是兩套SDK,初始化方法差異性較大,但是融云的性能較好,對消息本息存儲做API的比較容易理解和調用

1.網易IM在(有完整項目)項目有完整體現,包含了視頻會議,群聊,群視頻音頻通話,閱后即焚,單聊,且支持所有聊天消息類型,圖文,語音,文本,視頻,群公告,群鏈接等

2.融云在(有完整項目)項目有體現,具體包含了聊天室功能,用以直播間的實時評論

以上兩種用法暫不闡述,可以再具體項目中學習以及可以參照官方開發文檔進行開發,但是其中的性能優化等整體優化方案需由開發者自行設計,學自研發IM的同學可以多下載第三方的demo,參照其整體架構模式設計有很好的的幫助

下面著重講一下自研發IM的方式

1.首先自研發IM,要對socket有一定的了解,畢竟IM是基于長連接的實現方式。

2.完成所有API設計后打包成SDK供上層開發同學使用,這里涉及到的SDK的設計思路和打包方法后續樓主其他文章可以查閱。

1.socket的選型有socket,websocket,對兩種方式要有所了解

套接字(Socket)是通信的基石,是支持TCP/IP協議的網絡通信的基本操作單元。它是網絡通信過程中端點的抽象表示,包含進行網絡通信必須的五種信息:連接使用的協議,本地主機的IP地址,本地進程的協議端口,遠地主機的IP地址,遠地進程的協議端口。

應用層通過傳輸層進行數據通信時,TCP會遇到同時為多個應用程序進程提供并發服務的問題。多個TCP連接或多個應用程序進程可能需要通過同一個TCP協議端口傳輸數據。為了區別不同的應用程序進程和連接,許多計算機操作系統為應用程序與TCP/IP協議交互提供了套接字(Socket)接口。應用層可以和傳輸層通過Socket接口,區分來自不同應用程序進程或網絡連接的通信,實現數據傳輸的并發服務。

ok,看到這里還有蒙圈的同學,大抵是對網絡的七層協議理解的有所遺忘,所以回過頭需要把網絡的七層協議都了解一下方便知道每一層是如何工作的

OSI的7層從上到下分別是7應用層6表示層5會話層4傳輸層3網絡層2數據鏈路層1物理層;其中高層(即7、6、5、4層)定義了應用程序的功能,下面3層(即3、2、1層)主要面向通過網絡的端到端,點到點的數據流

參考文檔:https://baike.baidu.com/item/網絡七層協議/6056879?fr=aladdin,通讀文檔可以理解,高層是通過底層的接口來實現交互,低層也可以理解為我們ios的api底層,他只需要誰調用他時候,傳來參數即可,至于底層的實現協議和算法無需高層考慮,那么低層從高層就很好理解了,電信號,電流等表示物理層,光纖傳輸鏈路則為數據鏈路層,路由則為網絡層,而我們的tcp和udp就是傳輸層了,消息數據的傳遞就是會話層,數據的處理就是表示層,最后統一到底應用程序,就是應用層了。

而我們需要重點關注的是代碼配置方向的層面,物理層,鏈路層,會話層是不需要我們重點關注的,都是由硬件決定,軟件決定的范圍只有 應用層+會話層+傳輸層。

Tcp和UDP區別:

https://www.xinnet.com/xinzhi/65/118739.html

選型參考:

http://www.52im.net/thread-33-1-1.html?https://blog.csdn.net/qq_21521371/article/details/81199071?https://zhidao.baidu.com/question/563196162991295124.html

通過以上文章分析,目前我們采用TCP協議進行傳輸

可以揣測到微信是基于TCP的鏈接,部分采用UDP傳輸,部分采用TCP傳輸應該

3.下面就開始我們的套接字的選型了,套接字分為Socket和websocket,二者的區別

參考:https://blog.csdn.net/qushaming/article/details/90747326

?? ? ? ? https://www.cnblogs.com/barrywxx/p/7412808.html

webSocket是基于http短連接,輪詢,長輪詢之后誕生的基于http協議的應用層協議的一層協議,其是通過http建立連接,但是也是基于TCP協議傳輸,它必須依賴?HTTP 協議進行一次握手?,握手成功后,數據就直接從 TCP 通道傳輸,與 HTTP 無關了。而socket是基于數據傳輸層的協議,是虛擬出來的一層,可以理解為傳輸層和表示層中間的一種接口協議

4.iOS平臺有哪些WebSocketSocket的開源框架

Socket開源框架有:CocoaAsyncSocketsocketio/socket.io-client-swift

WebSocket開源框架有:facebook/SocketRockettidwall/SwiftWebSocket

OK到這里 webSocket的底層連接方法

開頭的鏈接中,將這些方法封裝在你自己的SDK中,并對數據進行處理,如存儲,加密,前后端定義好,并遵循SDK設計原則,將上層對接的同學需要的業務曝露在自己的API里面

5.單機最大的tcp連接數可以參考http://www.52im.net/thread-561-1-1.html,做單機垂直負載擴展的優化,然后在考慮分布負載的水平優化,做到最大限度的服務器優化

socket開發方式:

參考資料:http://www.lxweimin.com/p/0a11b2d0f4ae

下面說一下IM自研發/非自研發的整體架構可參考https://codingdict.com/os/software/65233?

1.所有點h合集的目標文件(類似PCH)CDChatList

2消息類型API CDChatListProtocols?

可以包含任何你想暴露出來的代理方法,屬性,枚舉

如:

typedef enum : NSUInteger {

? ? CDMessageTypeText,? ? ? //文字類型0

? ? CDMessageTypeImage,? ? //圖片類型1

? ? CDMessageTypeAudio,? ? //音頻類型2

? ? CDMessageTypeSystemInfo,//系統信息類型3

? ? CDMessageTypeVIDEO,? ? ? //視頻類型

? ? CDMessageTypeDING,? ? //視頻類型

? ? CDMessageTypeLocation,? //位置類型

? ? CDMessageTypeFile,? //文檔類型

? ? CDMessageTypeBig,//點贊大表情

? ? CDMessageTypeCancel,//撤回

? ? CDMessageTypeTouch,? // @類型

? ? CDMessageTypeReply,? //回復

? ? CDMessageTypeVoiceToText,//語音轉文字

? ? CDMessageTypeGroupAnn,//群公告

? ? CDMessageTypeBusinessCard,? //名片

? ? CDMessageTypeMeeting,? //會議消息

? ? CDMessageTypeVoiceWithVideo,//? 語音視頻

} CDMessageType;//消息類型

typedef enum : NSUInteger {

? ? CDMessageStateNormal,

?? ?CDMessageStateSending,? ? ? ? ? //圖片消息上傳中/文字消息發送中

? ? CDMessageStateSendFaild,? ? ? ? //消息發送失敗

? ? CDMessageStateDownloading,? ? ? //圖片消息下載中

? ? CDMessageStateDownloadFaild? ? //圖片消息下載失敗

} CDMessageState;

3.每一個大的功能既然都有單獨的一個單例類來管理,其涉及到的點擊事件也要單獨放在這個管理類里面,且要用多級代理的方式最終將點擊事件的具體實現引入到CDViewController.h層級中

目的:

1.便于管理,修改和維護

2.便于VC之間的交互,跳轉,數據傳遞等

如:CTMoreKeyBoard文件中的點擊事件

4.優化點:1.CTTextView文件中 textView設置為不可滾動,防止輸入跳動,則其高度根據輸入文字以及間距實時監聽并計算,修改其高度

5.以前微信一條消息的長按 會有兩種方式,1.長按出現復制,轉發等彈出框,一邊長按一邊橫向滑動會出現放大鏡,

那么 長按? 和長按橫向拖動 會有兩種彈出視圖切換,如何檢測

currentMode = CFRunLoopCopyCurrentMode(CFRunLoopGetMain());

? ? ? ? self.backgroundColor =[UIColor clearColor];

? ? ? ? _selectionStartPosition = 5;

? ? ? ? _selectionEndPosition = 1;

? ? ? ? [self setupGestures];

? ? ? ? __weak __typeof(self)weakSelf = self;

? ? ? ? CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault,kCFRunLoopAllActivities,YES,0,^(CFRunLoopObserverRef observer,CFRunLoopActivity activity){

? ? ? ? ? ? __strong __typeof(weakSelf)strongSelf = weakSelf;

? ? ? ? ? ? if(strongSelf==nil){

? ? ? ? ? ? ? ? return;

? ? ? ? ? ? }

? ? ? ? ? ? CFComparisonResult rest = CFStringCompare(strongSelf->currentMode,CFRunLoopCopyCurrentMode(CFRunLoopGetMain()),kCFCompareBackwards);

? ? ? ? ? ? if(rest != kCFCompareEqualTo){

? ? ? ? ? ? ? ? strongSelf->currentMode = CFRunLoopCopyCurrentMode(CFRunLoopGetMain());

? ? ? ? ? ? ? ? if((NSString *)CFBridgingRelease(strongSelf->currentMode)== UITrackingRunLoopMode){

? ? ? ? ? ? ? ? ? ? [strongSelf scrollDidScroll];

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? CFRunLoopAddObserver(CFRunLoopGetMain(),observer,kCFRunLoopCommonModes);

所以可以通過CFRunLoopObserverRef監聽,通過UITrackingRunLoopMode對比來處理拖動事件

5.coreText? 做IM的圖形排版,圖文混排的優勢

https://www.pianshen.com/article/41191695402/

6.新消息進來時候,更新的是消息列表的數據源,并更新整個tableView的總高,這里更新總高的時候,舊消息的高度是在消息模型中有存儲,而新消息的高度計算后并進行存儲,新消息的計算方式優化到coreText的排版引擎,并提前將文本內容進行渲染,而新消息的展示則直接在tableView的底部插入最新一行,不需要整體刷新,并且某一條數據若是出現不及時,卡頓時候需要用dispaycell進行預渲染刷新處理。

如何實現安全?

在SDK與服務器的連接建立過程中有一個復雜的秘鑰協商過程,首先客戶端需要生成一個一次性使用的加密秘鑰,并使用非對稱加密方式將這個秘鑰加密之后傳給服務器,加密數據會被服務器解密,之后該加密秘鑰被保留在該長連接的會話信息中,數據來往均使用該秘鑰加密,這是一個流式加密,可以有效防止中間人攻擊和數據包回放等攻擊手段。

微信IM資料:https://zhuanlan.zhihu.com/p/98350643

優化參考:http://www.lxweimin.com/p/cd441218b797

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容