百度公共IM系統(tǒng)的Andriod端IM SDK組件架構(gòu)設(shè)計(jì)與技術(shù)實(shí)現(xiàn)

本文由百度技術(shù)團(tuán)隊(duì)分享,引用自百度Geek說(shuō),原題“百度Android IM SDK組件能力建設(shè)及應(yīng)用”,本文進(jìn)行了排版和內(nèi)容優(yōu)化。

1、引言

移動(dòng)互聯(lián)網(wǎng)時(shí)代,隨著社交媒體、移動(dòng)支付、線上購(gòu)物等行業(yè)的快速發(fā)展,對(duì)即時(shí)通訊功能的需求不斷增加。對(duì)于各APP而言,接入IM SDK(即時(shí)通訊軟件開(kāi)發(fā)工具包)能夠大大降低開(kāi)發(fā)成本、提高開(kāi)發(fā)效率,快速構(gòu)建自己的IM系統(tǒng)。

本文主要介紹了百度公共IM系統(tǒng)的Andriod端IM SDK的建設(shè)背景、IM SDK主要結(jié)構(gòu)和工作流程以及建設(shè)過(guò)程遇到的問(wèn)題和解決方案。

* 推薦閱讀:百度技術(shù)團(tuán)隊(duì)分享的另一篇關(guān)于IM能力的文章《揭秘百度IM消息中臺(tái)的全量用戶(hù)消息推送技術(shù)改造實(shí)踐》。

2、認(rèn)識(shí)IM系統(tǒng)

2.1IM系統(tǒng)發(fā)展背景

近年來(lái),隨著互聯(lián)網(wǎng)的普及和移動(dòng)通信技術(shù)技術(shù)的快速發(fā)展,智能手機(jī)、平板電腦等移動(dòng)設(shè)備的普及讓越來(lái)越多的人享受到便捷的網(wǎng)絡(luò)服務(wù)。這為即時(shí)通訊系統(tǒng)的發(fā)展提供了廣泛的用戶(hù)基礎(chǔ)。

傳統(tǒng)的通訊工具如電話、短信等在滿足用戶(hù)需求方面存在一定的局限性,無(wú)法實(shí)現(xiàn)高效、便捷地溝通。即時(shí)通訊系統(tǒng)應(yīng)運(yùn)而生,以其強(qiáng)大的功能和便捷的體驗(yàn)滿足了用戶(hù)的便捷、高效通訊的需求。

2.2IM系統(tǒng)簡(jiǎn)介

即時(shí)通訊系統(tǒng)(Instant Messaging,簡(jiǎn)稱(chēng)IM系統(tǒng))是一種允許用戶(hù)通過(guò)互聯(lián)網(wǎng)實(shí)時(shí)交換信息的通信技術(shù)。核心功能包括消息的發(fā)送與接收、用戶(hù)狀態(tài)的管理、消息、會(huì)話的存儲(chǔ)與檢索等。為了更好地滿足用戶(hù)更多場(chǎng)景訴求,IM系統(tǒng)還提供了如群組聊天、文件傳輸、語(yǔ)音和視頻通話等功能。

PS:更多知識(shí)可以深入閱讀《零基礎(chǔ)IM開(kāi)發(fā)入門(mén)(一):什么是IM系統(tǒng)?》、《知識(shí)科普:IM聊天應(yīng)用是如何將消息發(fā)送給對(duì)方的?(非技術(shù)篇)》。

2.3IM系統(tǒng)應(yīng)用場(chǎng)景

即時(shí)通訊系統(tǒng)的發(fā)展經(jīng)歷了從早期的在線聊天室、ICQ、MSN等個(gè)人即時(shí)通訊軟件,到如今功能豐富的聊天社交軟件(如QQ、微信)、企業(yè)級(jí)即時(shí)通訊系統(tǒng)(如釘釘、企業(yè)微信、飛書(shū)、如流)、應(yīng)用內(nèi)必備的IM能力(如百度、微博、小紅書(shū)、抖音等APP中消息模塊)等應(yīng)用場(chǎng)景。

IM系統(tǒng)因其實(shí)時(shí)性、便捷性和功能多樣性,已經(jīng)成為現(xiàn)代社會(huì)溝通不可或缺的工具,并且隨著技術(shù)的發(fā)展,其應(yīng)用場(chǎng)景還在不斷擴(kuò)展。

PS:移動(dòng)互聯(lián)網(wǎng)時(shí)代的IM產(chǎn)品進(jìn)化史可詳讀《盤(pán)點(diǎn)移動(dòng)互聯(lián)網(wǎng)時(shí)代的社交產(chǎn)品進(jìn)化史(上篇):誰(shuí)主沉浮》、《盤(pán)點(diǎn)移動(dòng)互聯(lián)網(wǎng)時(shí)代的社交產(chǎn)品進(jìn)化史(下篇):大浪淘沙》。

3、百度公共IM系統(tǒng)背景

在百度公司內(nèi)部,存在如百度APP、文心一言APP、百度貼吧APP、好看視頻APP等各類(lèi)APP,各業(yè)務(wù)各自搭建一套完整的IM系統(tǒng)存在開(kāi)發(fā)、維護(hù)成本高,系統(tǒng)重復(fù)等問(wèn)題。

因此,搭建一套公共的能夠滿足各產(chǎn)品線訴求的完整IM系統(tǒng)勢(shì)在必行。各業(yè)務(wù)只需獨(dú)立接入公共IM系統(tǒng)即可實(shí)現(xiàn)業(yè)務(wù)自己的IM相關(guān)功能,大大降低了開(kāi)發(fā)、維護(hù)成本和IM系統(tǒng)使用門(mén)檻,提高了業(yè)務(wù)IM功能開(kāi)發(fā)、迭代效率。

4、公共IM系統(tǒng)整體結(jié)構(gòu)

對(duì)于公司內(nèi)業(yè)務(wù)而言,對(duì)于IM能力訴求各有差異:

1)有的業(yè)務(wù)希望最小成本構(gòu)建自己的IM服務(wù),希望提供一套從消息收發(fā)到上層聊天交互的完整服務(wù);

2)有的業(yè)務(wù)希望使用自己的UI套件;

3)有的業(yè)務(wù)只想使用粉絲群能力;

4)也有業(yè)務(wù)有自己的UI和業(yè)務(wù)邏輯,只想使用基礎(chǔ)、實(shí)時(shí)、穩(wěn)定的消息通道。

為了滿足各業(yè)務(wù)/產(chǎn)品線各類(lèi)訴求,需要將IM系統(tǒng)能力進(jìn)行拆分、封裝,提供不同能力粒度的IM組件。

百度公共IM系統(tǒng)由客戶(hù)端IM 套件(IM SDK、長(zhǎng)連接SDK、IM插件、群聊組件)和服務(wù)端IM服務(wù)組成。

公共IM系統(tǒng)服務(wù)各業(yè)務(wù)方案結(jié)構(gòu)如下:

基礎(chǔ)服務(wù)層主要由公共IM系統(tǒng)中客戶(hù)端IM套件、服務(wù)端IM服務(wù),以及業(yè)務(wù)自己服務(wù)端組成。

業(yè)務(wù)客戶(hù)端通過(guò)接入IM SDK、長(zhǎng)連接SDK實(shí)現(xiàn)業(yè)務(wù)客戶(hù)端內(nèi)IM相關(guān)能力,業(yè)務(wù)服務(wù)端通過(guò)接入公共IM系統(tǒng)中的服務(wù)端對(duì)外接口層,實(shí)現(xiàn)業(yè)務(wù)服務(wù)端消息發(fā)送和接收。通過(guò)業(yè)務(wù)客戶(hù)端和服務(wù)單接入IM客戶(hù)端套件和服務(wù)端,實(shí)現(xiàn)從業(yè)務(wù)端到業(yè)務(wù)服務(wù)端的雙向觸達(dá)。

其中:

1)?業(yè)務(wù)服務(wù)端:業(yè)務(wù)自己的服務(wù)端主要負(fù)責(zé)業(yè)務(wù)相關(guān)的業(yè)務(wù)邏輯處理,通過(guò)調(diào)用IM 服務(wù)端提供的公共接口進(jìn)行消息發(fā)送,接收IM 服務(wù)端推送的消息,進(jìn)行業(yè)務(wù)自有邏輯處理,根據(jù)業(yè)務(wù)自身情況決定是否自己持有數(shù)據(jù)。

2)IM 服務(wù)端:提供實(shí)時(shí)、安全、穩(wěn)定的登錄服務(wù)、消息收發(fā),消息會(huì)話同步、通知,消息、會(huì)話管理,用戶(hù)信息管理、設(shè)置管理等服務(wù)。提供各服務(wù)對(duì)端接口,暴露對(duì)業(yè)務(wù)公共接口,方便業(yè)務(wù)快速接入。

3)??長(zhǎng)連接SDK主要職責(zé):長(zhǎng)連接SDK主要通過(guò)約定數(shù)據(jù)協(xié)議、數(shù)據(jù)加解密、訪問(wèn)控制、數(shù)據(jù)壓縮、創(chuàng)建、維護(hù)連接,處理異常等機(jī)制保證數(shù)據(jù)實(shí)時(shí)、安全、高效傳輸。

4)?IM SDK主要職責(zé):IM SDK主要負(fù)責(zé)IM相關(guān)端業(yè)務(wù)邏輯處理,包括登錄服務(wù)、消息、會(huì)話管理、未讀數(shù)管理、用戶(hù)、設(shè)置管理等能力。用戶(hù)使用手機(jī)進(jìn)行消息發(fā)送,使用IM 服務(wù)端對(duì)端接口協(xié)議,通過(guò)長(zhǎng)連接SDK數(shù)據(jù)通道將消息發(fā)送到IM 服務(wù)端;通過(guò)長(zhǎng)連接通道接收IM 服務(wù)端推送消息,經(jīng)過(guò)業(yè)務(wù)邏輯處理后,觸達(dá)到用戶(hù)。

5)?IM插件主要職責(zé):通過(guò)長(zhǎng)連接SDK構(gòu)建消息通道,使用IM SDK提供的IM邏輯服務(wù)層,增加聊天頁(yè)、設(shè)置頁(yè)等相關(guān)UI能力,打包構(gòu)建出能夠直接集成使用的聊天組件。

6)?群聊組件主要職責(zé):通過(guò)長(zhǎng)連接SDK構(gòu)建消息通道,使用IM SDK提供的IM邏輯服務(wù)層,將群聊相關(guān)UI頁(yè)面組合打包,輸出包含完整群聊能力可直接集成的群聊組件。

5、Android端IM SDK的整體架構(gòu)

Android IM SDK整體由公共接口層、業(yè)務(wù)層和數(shù)據(jù)層組成,其中:

1)接口層:根據(jù)業(yè)務(wù)需要,對(duì)外統(tǒng)一提供消息、會(huì)話、設(shè)置項(xiàng)等相關(guān)操作接口以及未讀數(shù)、成員等相關(guān)查詢(xún)接口;

2)業(yè)務(wù)層:在原始數(shù)據(jù)基礎(chǔ)上增加業(yè)務(wù)相關(guān)邏輯,通過(guò)接口層返回給SDK使用方。

3)數(shù)據(jù)層:數(shù)據(jù)層主要包含業(yè)務(wù)產(chǎn)生的原始數(shù)據(jù)的存儲(chǔ)以及對(duì)原始數(shù)據(jù)的最原始操作。

業(yè)務(wù)層包括但不限于以下主要模塊:

1)登錄管理:負(fù)責(zé)在IM SDK初始化后長(zhǎng)連接建連、重連,百度賬號(hào)體系登錄、退登、重登等情況下,IM 系統(tǒng)的登錄、退登,登錄信息、事件管理以及異常處理機(jī)制等;

2)同步管理:負(fù)責(zé)在IM登錄后同步單聊、群聊會(huì)話,消息、通知消息等賬號(hào)內(nèi)相關(guān)數(shù)據(jù);

3)配置管理:登錄后負(fù)責(zé)管理用戶(hù)在IM系統(tǒng)中相關(guān)全部配置項(xiàng);

4)通知管理:負(fù)責(zé)用戶(hù)處于在線/離線狀態(tài)時(shí)系統(tǒng)通知處理,包括但不限于通知監(jiān)聽(tīng)、解析、指令調(diào)度分發(fā)等操作;

5)消息管理:基于原始消息數(shù)據(jù),提供消息發(fā)送、刪除、更新、撤回、查詢(xún)等操作;

6)會(huì)話管理:負(fù)責(zé)基礎(chǔ)會(huì)話數(shù)據(jù)管理以及會(huì)話創(chuàng)建、更新、刪除、查詢(xún)以及會(huì)話監(jiān)聽(tīng)管理、變更分發(fā)等機(jī)制;

7)群成員/好友管理:管理登錄后會(huì)話中的一些聯(lián)系人數(shù)據(jù)以及群成員信息;

8)群管理:負(fù)責(zé)管理群消息、群操作(如拉人、 踢人、退群、解散、禁言、增加管理員等操作);

6、Android端IM SDK的核心流程概覽

登錄同步主要流程:

消息上下行主要流程:

在IM SDK整個(gè)工作流程中,核心流程主要包括:

1)登錄管理:初始化、長(zhǎng)連接連接管理、IM登錄、退登等;

2)數(shù)據(jù)同步:消息、會(huì)話用戶(hù)信息等數(shù)據(jù)同步;

3)通知管理:離線、在線通知處理;

4)消息上下行等核心流程。

IM SDK組件要在保證消息安全、可靠、實(shí)時(shí)觸達(dá)到用戶(hù)的同時(shí),還要避免消息丟失、重復(fù)、用戶(hù)離線狀態(tài)消息丟失、在線或離線狀態(tài)多端數(shù)據(jù)不一致、以及未讀數(shù)不一致等問(wèn)題。

PS:相關(guān)文章可以詳讀以下幾篇:

零基礎(chǔ)IM開(kāi)發(fā)入門(mén)(三):什么是IM系統(tǒng)的可靠性?

零基礎(chǔ)IM開(kāi)發(fā)入門(mén)(四):什么是IM系統(tǒng)的消息時(shí)序一致性?

IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(一):保證在線實(shí)時(shí)消息的可靠投遞

IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(二):保證離線消息的可靠投遞

如何保證IM實(shí)時(shí)消息的“時(shí)序性”與“一致性”?

談?wù)勔苿?dòng)端 IM 開(kāi)發(fā)中登錄請(qǐng)求的優(yōu)化

移動(dòng)端IM登錄時(shí)拉取數(shù)據(jù)如何作到省流量?

淺談移動(dòng)端IM的多點(diǎn)登錄和消息漫游原理

下面的章節(jié)是關(guān)于IM SDK核心流程詳細(xì)介紹。

7、核心流程1:登錄管理

IM系統(tǒng)登錄成功是使用IM服務(wù)的前提,準(zhǔn)備使用IM服務(wù)時(shí),要對(duì)IM SDK依賴(lài)的基礎(chǔ)環(huán)境、功能能力進(jìn)行初始化配置,達(dá)到環(huán)境可用后才能登錄系統(tǒng),IM系統(tǒng)登錄成功后,才能完整使用IM SDK提供能力。

挑戰(zhàn):依賴(lài)的運(yùn)行環(huán)境變更時(shí),如何快速恢復(fù)?

問(wèn)題描述:完整的IM工作環(huán)境需要有正常的網(wǎng)絡(luò),百度賬號(hào)登錄且狀態(tài)正常,長(zhǎng)連接穩(wěn)定可用等,如果其中一個(gè)必要依賴(lài)異常時(shí),IM系統(tǒng)便處于異常狀態(tài),無(wú)法繼續(xù)完整使用IM SDK能力,出現(xiàn)SDK接口調(diào)用結(jié)果不符合預(yù)期的情況。比如網(wǎng)絡(luò)斷開(kāi)或不可用時(shí),長(zhǎng)連接處于斷連狀態(tài),對(duì)IM SDK如何感知?網(wǎng)絡(luò)再次可用時(shí),IM 服務(wù)如何恢復(fù)?IM服務(wù)不可用時(shí),無(wú)法接收到新消息,IM服務(wù)恢復(fù)后,如何系統(tǒng)性地恢復(fù)?

問(wèn)題解決(異?;謴?fù)機(jī)制):此類(lèi)問(wèn)題發(fā)生后,為了避免IM服務(wù)長(zhǎng)期不可使用,需要增加異?;謴?fù)機(jī)制,使得某些環(huán)境條件恢復(fù)正常時(shí),IM系統(tǒng)服務(wù)能夠快速恢復(fù)到最新?tīng)顟B(tài)。

主要工作包含:

1)異常捕捉:增加網(wǎng)絡(luò)環(huán)境、賬號(hào)登錄狀態(tài)、長(zhǎng)連接連接狀態(tài)等環(huán)境監(jiān)聽(tīng)感知;

2)異常反饋:捕獲異常后,需要在調(diào)用SDK接口時(shí)將用戶(hù)相關(guān)環(huán)境異常信息返回,反饋給調(diào)用方;

3)服務(wù)快速恢復(fù):感知依賴(lài)環(huán)境恢復(fù)后,自動(dòng)對(duì)流程中依賴(lài)重新配置,重新登錄IM服務(wù),恢復(fù)服務(wù)不可用期間用戶(hù)數(shù)據(jù);

其中其核心流程如下:

具體是:

1)正常流程下:百度賬號(hào)登錄后初始化IM SDK,IM SDK針對(duì)賬號(hào)、長(zhǎng)連接等增加狀態(tài)監(jiān)聽(tīng)(還包含IM相關(guān)消息、會(huì)話、用戶(hù)信息等變更等業(yè)務(wù)相關(guān)監(jiān)聽(tīng)),登錄長(zhǎng)連接會(huì)登錄IM系統(tǒng),IM系統(tǒng)登錄成功后同步用戶(hù)消息數(shù)據(jù);

2)長(zhǎng)連接狀態(tài)異常:長(zhǎng)連接由于客戶(hù)端網(wǎng)絡(luò)或服務(wù)異常導(dǎo)致連接斷開(kāi)時(shí),根據(jù)IM SDK服務(wù)不可用,長(zhǎng)連接重新連接后重新登錄IM系統(tǒng),登錄成功后增量同步用戶(hù)服務(wù)不可用之后的數(shù)據(jù);

3)賬號(hào)狀態(tài)異常:當(dāng)用戶(hù)退出賬號(hào)登錄時(shí),會(huì)先退出原賬號(hào)登錄,切換為游客用戶(hù)登錄;當(dāng)用戶(hù)切換為其他賬號(hào)時(shí),會(huì)先退出原賬號(hào)登錄,切換為新賬號(hào)登錄;增量同步用戶(hù)服務(wù)賬號(hào)時(shí)刻之后的數(shù)據(jù)。

通過(guò)以上流程,可以很好地避免因?yàn)榫W(wǎng)絡(luò)、長(zhǎng)連接狀態(tài)、賬號(hào)狀態(tài)變更時(shí),IM服務(wù)能夠快速重試,重置登錄配置,重新登錄IM,快速恢復(fù)用戶(hù)數(shù)據(jù),保持狀態(tài)異常前后,消息及時(shí)觸達(dá)。

8、 核心流程2:數(shù)據(jù)同步

IM登錄成功后,需要通過(guò)長(zhǎng)連接SDK從服務(wù)端全量或增量同步當(dāng)前用戶(hù)離線階段產(chǎn)生的單聊、群聊會(huì)話、消息、聯(lián)系人/群成員信息等數(shù)據(jù),更新未讀數(shù)、會(huì)話中l(wèi)astMsg等操作,保持用戶(hù)本地和服務(wù)端遠(yuǎn)程數(shù)據(jù)一致。

8.1挑戰(zhàn)一:如何提升客戶(hù)端和服務(wù)端性能的

問(wèn)題描述:IM SDK在賬號(hào)登錄后,會(huì)登錄IM系統(tǒng),由于賬號(hào)登錄狀態(tài)時(shí)效較長(zhǎng),絕大部分情況下賬號(hào)均處于登錄狀態(tài),每次啟動(dòng)APP時(shí)都會(huì)請(qǐng)求IM登錄,IM登錄后再同步用戶(hù)會(huì)話和消息。百度APP擁有上億用戶(hù),在用戶(hù)集中使用APP的時(shí)間區(qū)間內(nèi),qps量級(jí)非常大,在服務(wù)端資源有限的情況下,大qps量級(jí)對(duì)IM服務(wù)端是一個(gè)不小的挑戰(zhàn)。為了保持服務(wù)的穩(wěn)定性,在資源有限的情況下,需要在業(yè)務(wù)邏輯上對(duì)請(qǐng)求做優(yōu)化,降低服務(wù)qps,保持服務(wù)穩(wěn)定可用。

問(wèn)題解決:(會(huì)話拉取versionCode機(jī)制+消息拉取隊(duì)列):針對(duì)以上背景,優(yōu)化的核心主要是在業(yè)務(wù)邏輯上減少I(mǎi)M登錄到IM同步期間的服務(wù)端請(qǐng)求。

主要優(yōu)化點(diǎn)如下:

1)客戶(hù)端登錄后減少非必須請(qǐng)求,總未讀數(shù)獲取由從服務(wù)端獲取,改為先使用客戶(hù)端本地計(jì)算,同步數(shù)據(jù)后再更新;

2)客戶(hù)端每次同步會(huì)話時(shí),將所有新會(huì)話放入同步隊(duì)列中,防止每個(gè)會(huì)話開(kāi)一個(gè)線程,增加客戶(hù)端線程池飽和風(fēng)險(xiǎn),減少服務(wù)端并發(fā)請(qǐng)求。

3)服務(wù)端對(duì)會(huì)話同步請(qǐng)求增加versionCode機(jī)制:每次客戶(hù)端請(qǐng)求獲取會(huì)話后,服務(wù)端返回一個(gè)versionCode(如果后續(xù)有新會(huì)話,才會(huì)更新versionCode),客戶(hù)端下次登錄再請(qǐng)求拉會(huì)話時(shí)如果傳參的versionCode和服務(wù)端最新的versionCode一致,表示沒(méi)有新會(huì)話,不需要查庫(kù)等操作,直接返回空結(jié)果。

主要流程如下:

8.2挑戰(zhàn)二:如何避免同步失敗時(shí)消息丟失問(wèn)題

問(wèn)題描述:為了降低服務(wù)端qps,在拉取會(huì)話時(shí)增加了versionCode機(jī)制,如果第一次拉取會(huì)話后沒(méi)有新會(huì)話產(chǎn)生,后續(xù)拉會(huì)話時(shí)服務(wù)端根據(jù)versionCode判斷服務(wù)端和客戶(hù)端傳參versionCode一致,表示端上會(huì)話列表和服務(wù)端一致,直接返回結(jié)果,表示沒(méi)有新會(huì)話返回。如果在拉取完會(huì)話后,每條會(huì)話消息還未拉去完畢,此時(shí)斷網(wǎng)或長(zhǎng)連接中斷,導(dǎo)致部分會(huì)話的消息沒(méi)有拉取或沒(méi)有拉取完畢,狀態(tài)恢復(fù)再次重試?yán)r(shí)由于已經(jīng)獲取到了最新的versionCode,再次從server拉取會(huì)話時(shí)無(wú)法拉取到會(huì)話,導(dǎo)致部分會(huì)話消息丟失。

如果拉取某條會(huì)話的消息時(shí),拉取請(qǐng)求服務(wù)異常,如果拋棄當(dāng)前任務(wù)執(zhí)行之后的任務(wù),依然請(qǐng)求異常,導(dǎo)致隊(duì)列中后續(xù)部分或剩余所有任務(wù)請(qǐng)求失敗,消息拉取失敗,導(dǎo)致無(wú)法拉取到部分會(huì)話消息,導(dǎo)致消息丟失。

問(wèn)題解決(versionCode延遲記錄+重試機(jī)制):

1)根據(jù)以上問(wèn)題描述,對(duì)于問(wèn)題1,需要保持versionCode的有效性,對(duì)于問(wèn)題一發(fā)生時(shí),客戶(hù)端當(dāng)次獲取的versionCode其實(shí)已經(jīng)是失效狀態(tài),需要在會(huì)話、消息都拉取完畢時(shí)記錄versionCode,保持客戶(hù)端本地和服務(wù)端均有效。

2)對(duì)于問(wèn)題2,隊(duì)列中的任務(wù)要根據(jù)具體異常執(zhí)行跳過(guò)策略,如果是因?yàn)榉?wù)端內(nèi)部錯(cuò)誤導(dǎo)致的同步失敗,可以跳過(guò),對(duì)于網(wǎng)絡(luò)或長(zhǎng)連接狀態(tài)異常,可以增加重試機(jī)制,超過(guò)重試次數(shù)才停止任務(wù),從而增加消息拉取成功率。

主要流程如下:

9、核心流程3:通知管理

9.1概述

通知下行:用戶(hù)在線階段,如過(guò)有新消息或者消息已讀、刪除、會(huì)話刪除、置頂、免打擾狀態(tài)變更等多端同步情況時(shí),服務(wù)端會(huì)下行對(duì)應(yīng)通知消息,通知當(dāng)前登錄設(shè)備處理新操作。

以新消息通知為例:如果有其他用戶(hù)給當(dāng)前用戶(hù)發(fā)送消息,消息到達(dá)服務(wù)端后,服務(wù)端根據(jù)用戶(hù)在線狀態(tài),通過(guò)長(zhǎng)連接通道下發(fā)新消息通知;端根據(jù)約定解析對(duì)應(yīng)通知消息,識(shí)別新消息通知,開(kāi)始拉取新消息操作,拉取新消息后更新會(huì)話lastMsg、未讀數(shù)相關(guān)信息,轉(zhuǎn)發(fā)變更到業(yè)務(wù)層,更新UI交互。

9.2挑戰(zhàn)一:如何實(shí)現(xiàn)同一賬號(hào)在線設(shè)備操作后,其他離線設(shè)備在線時(shí)用戶(hù)數(shù)據(jù)一致性

問(wèn)題概述:如果同一用戶(hù)有多臺(tái)手機(jī),用戶(hù)部分設(shè)備處于離線狀態(tài)(設(shè)備斷網(wǎng)或未打開(kāi)APP),如果用戶(hù)使用在線狀態(tài)的手機(jī)執(zhí)行了已讀會(huì)話、刪除會(huì)話、刪除消息等操作,操作完畢后,再打開(kāi)離線的設(shè)備,使其保持在線狀態(tài),此時(shí)剛保持在線狀態(tài)的設(shè)備會(huì)話、消息、未讀數(shù)狀態(tài)仍未改變,出現(xiàn)兩臺(tái)設(shè)備消息/會(huì)話等狀態(tài)不一致問(wèn)題。

以已讀操作為例:如果當(dāng)前用戶(hù)兩臺(tái)設(shè)備(設(shè)備A和設(shè)備B)都收到了用戶(hù)小明發(fā)來(lái)的5條消息,設(shè)備B斷網(wǎng)或APP進(jìn)程關(guān)閉。用戶(hù)使用一臺(tái)設(shè)備A已讀了和用戶(hù)小明的聊天信息,設(shè)備A中和用戶(hù)小明的聊天會(huì)話中未讀數(shù)變?yōu)?;打開(kāi)設(shè)備B,使其處于在線狀態(tài),設(shè)備B和用戶(hù)小明的會(huì)話仍顯示有5條未讀數(shù)。

問(wèn)題解決(指令機(jī)制):對(duì)于此類(lèi)用戶(hù)多設(shè)備的在線狀態(tài)不一致的情況,操作APP內(nèi)消息或會(huì)話后,出現(xiàn)用戶(hù)多臺(tái)設(shè)備在線時(shí)設(shè)備數(shù)據(jù)不一致問(wèn)題,問(wèn)題根源在于設(shè)備B重新在線后無(wú)法感知到設(shè)備A的操作,如果設(shè)備B重新在線后能獲取到設(shè)備A的操作,并執(zhí)行設(shè)備A的操作,就能保持兩臺(tái)(或多臺(tái))設(shè)備數(shù)據(jù)一致。

需要把用戶(hù)操作數(shù)據(jù)化,將用戶(hù)操作構(gòu)造為一條“指令”消息保存到服務(wù)端,等設(shè)備再次在線后,拉取到離線期間未接收到的消息后,拉取設(shè)備離線期間的操作指令消息,解析指令消息后,執(zhí)行對(duì)應(yīng)的操作。

以設(shè)備在線后消息已讀指令消息為例,相關(guān)執(zhí)行流程如下:

9.3挑戰(zhàn)二:如何實(shí)現(xiàn)同一賬號(hào)多臺(tái)在線設(shè)備數(shù)據(jù)一致性

問(wèn)題概述:IM系統(tǒng)中,數(shù)據(jù)一致性是指在多設(shè)備環(huán)境中,用戶(hù)如果有多臺(tái)設(shè)備或終端,各個(gè)設(shè)備登錄同一賬號(hào),各個(gè)設(shè)備下顯示的用戶(hù)消息數(shù)量、消息未讀狀態(tài)、會(huì)話未讀數(shù)、會(huì)話最近一條消息等要保持一致。

實(shí)際生活場(chǎng)景下,一個(gè)用戶(hù)存在多臺(tái)設(shè)備,可能存在如下情case,即設(shè)備全部處于在線狀態(tài)。

如果當(dāng)前用戶(hù)使用一臺(tái)設(shè)備(例如設(shè)備A)向用戶(hù)“小明”發(fā)送一條內(nèi)容為“你好啊”的消息,當(dāng)前用戶(hù)的另一臺(tái)設(shè)備(例如設(shè)備B)也需要在和用戶(hù)小明的聊天也中顯示自己發(fā)送了一條內(nèi)容為“你好啊”的消息內(nèi)容。

問(wèn)題解決(多端同步機(jī)制):對(duì)于同一賬號(hào)登錄多個(gè)設(shè)備的情況,設(shè)備均在線時(shí),如果其中一臺(tái)設(shè)備發(fā)送一條消息(或者進(jìn)行已讀、刪除消息、刪除會(huì)話、修改會(huì)話置頂、免打擾狀態(tài)等操作),服務(wù)端會(huì)將新發(fā)送的消息通知推送到登錄同一賬號(hào)的其他設(shè)備上,其他設(shè)備接收到新消息通知后,再去拉取當(dāng)前賬號(hào)在其他設(shè)備發(fā)送的消息,更新會(huì)話,從而達(dá)到登錄同一賬號(hào)的多臺(tái)設(shè)備數(shù)據(jù)同步,保持?jǐn)?shù)據(jù)一致性。

每個(gè)操作對(duì)應(yīng)于一條通知消息,登錄后同步當(dāng)前設(shè)備離線期間產(chǎn)生的通知消息后,根據(jù)通知消息里攜帶的操作信息,再次執(zhí)行對(duì)應(yīng)的操作,實(shí)現(xiàn)多端同步效果。

10、核心流程4:消息收發(fā)

10.1挑戰(zhàn)一:以什么樣的方式獲取新消息

問(wèn)題描述:當(dāng)有其他用戶(hù)給當(dāng)前設(shè)備發(fā)消息時(shí),要實(shí)時(shí)展現(xiàn)其他用戶(hù)發(fā)送的消息,就要及時(shí)地獲取到對(duì)應(yīng)消息。

大概存在幾種方案:

解決方案(推拉結(jié)合):綜合以上方案,保證服務(wù)穩(wěn)定性是系統(tǒng)的關(guān)鍵,想要消息不丟失,并且能穩(wěn)定觸達(dá)的同時(shí)還要保證客戶(hù)端和服務(wù)端系統(tǒng)的穩(wěn)定性,推拉結(jié)合的方案更適合。

方案描述:用戶(hù)發(fā)送新消息時(shí),服務(wù)端揀選新消息關(guān)鍵信息字段,構(gòu)造一條通知消息推送給接收人。接收人收到通知消息后,解析通知消息內(nèi)容,理解對(duì)用通知操作后,從服務(wù)端拉取新消息。

10.2挑戰(zhàn)二:如何保證消息可靠投遞

問(wèn)題描述:系統(tǒng)需要保證消息的可靠傳輸,不會(huì)丟失或重復(fù),確保消息的順序和完整性。

IM系統(tǒng)的消息“可靠性”,通常就是指聊天消息可靠投遞。即對(duì)于消息發(fā)送方發(fā)出消息,要保證消息接收方及時(shí)、順序接收到,并在UI中正常展示(不丟失、不重復(fù))。(PS:相關(guān)文章可閱讀《零基礎(chǔ)IM開(kāi)發(fā)入門(mén)(三):什么是IM系統(tǒng)的可靠性?》)

在現(xiàn)實(shí)的使用場(chǎng)景中,從發(fā)送方點(diǎn)擊「發(fā)送」按鈕到接收方接收到消息,發(fā)送接收消息的整條鏈路中包含:

1)消息協(xié)議組裝;

2)長(zhǎng)連接通道發(fā)消息;

3)服務(wù)端接收到消息;

4)服務(wù)端保存消息;

5)服務(wù)端通過(guò)長(zhǎng)連接下行通知消息;

6)接收方根據(jù)通知拉取消息。

如果發(fā)送消息時(shí)接收方處理離線狀態(tài),或者發(fā)送消息時(shí)長(zhǎng)連接因?yàn)榫W(wǎng)絡(luò)或異常中斷、服務(wù)端服務(wù)異常、消息下行時(shí)長(zhǎng)連接異常等情況下,鏈路中任意一環(huán)異常導(dǎo)致鏈路中斷均會(huì)導(dǎo)致消息無(wú)法到達(dá)接收方,即消息丟失。

大致分為:

1)消息上行階段消息丟失;

2)消息下行階段消息丟失。

解決方案(失敗重試與重連拉取機(jī)制):想要保證實(shí)時(shí)&離線消息的可靠投遞,需要對(duì)收發(fā)消息的整條鏈路各階段增加從產(chǎn)品交互到技術(shù)方案上增加兜底和容錯(cuò)處理。

消息上行服務(wù)異常處理增加失敗重試機(jī)制:

IM SDK發(fā)送上行請(qǐng)求,長(zhǎng)連接因?yàn)榫W(wǎng)絡(luò)或其他原因?qū)е麻L(zhǎng)連接服務(wù)不可用、服務(wù)端服務(wù)異常時(shí),消息發(fā)送失敗,需要對(duì)發(fā)送失敗的消息做標(biāo)記,UI上提供視覺(jué)展示,增加重新發(fā)送機(jī)制,在交互上避免用戶(hù)發(fā)消息失敗時(shí)出現(xiàn)消息已發(fā)送對(duì)方收不到的錯(cuò)誤預(yù)期,提高服務(wù)恢復(fù)時(shí)功能可用性。

消息下行重新拉取機(jī)制流程如下:

具體是:

1)對(duì)于服務(wù)端推送到客戶(hù)端的消息,服務(wù)端需要將消息存儲(chǔ),如果用戶(hù)處于在線狀態(tài),則推送新消息通知給接收用戶(hù);

2)如果服務(wù)端推送下行通知消息時(shí),接收方長(zhǎng)連接服務(wù)處于不可用/不穩(wěn)定的情況,端需要增加長(zhǎng)連接連接狀態(tài)監(jiān)測(cè),重連拉取機(jī)制;監(jiān)測(cè)到長(zhǎng)連接重新連接后,主動(dòng)重新拉取服務(wù)不可用時(shí)刻之后的消息,保障用戶(hù)能夠及時(shí)看到離線期間漏掉的消息。

11、本文小結(jié)

根據(jù)各類(lèi)APP對(duì)于IM系統(tǒng)不同構(gòu)建方案訴求,百度公共IM系統(tǒng)提供了包含IM各類(lèi)能力粒度、高內(nèi)聚、可擴(kuò)展的長(zhǎng)連接 SDK、IM SDK、IM聊天插件、群聊組件;提供了中臺(tái)NA容器、HN容器、公共Web容器下IM聊天頁(yè)接入方案;依托IM 服務(wù)端,提供了一套實(shí)時(shí)、可靠、穩(wěn)定的IM服務(wù)。滿足了各業(yè)務(wù)方快速、高效構(gòu)建各自產(chǎn)品線IM能力的愿望,大大提高了開(kāi)發(fā)效率、降低了開(kāi)發(fā)成本。

實(shí)時(shí)、可靠、安全是對(duì)IM系統(tǒng)的基礎(chǔ)要求,系統(tǒng)地收發(fā)消息機(jī)制提供了最小粒度的IM服務(wù),實(shí)時(shí)通知、離線獲取能夠更好地保障IM功能完整性,實(shí)時(shí)、離線多端同步能力提升了同一賬號(hào)多臺(tái)設(shè)備的產(chǎn)品體驗(yàn)。以功能、交互體驗(yàn)需求為出發(fā)點(diǎn)而進(jìn)行方案設(shè)計(jì)的同時(shí)也要考慮產(chǎn)品性能以及端、服務(wù)端、業(yè)務(wù)的實(shí)現(xiàn)成本。

隨著用戶(hù)需求和市場(chǎng)變化,我們需要不斷迭代優(yōu)化,升級(jí)系統(tǒng)功能和性能,更細(xì)致、高效地滿足業(yè)務(wù)訴求,為用戶(hù)提供更加優(yōu)質(zhì)、高效的即時(shí)通訊服務(wù)。

12、參考資料

[1]?零基礎(chǔ)IM開(kāi)發(fā)入門(mén)(一):什么是IM系統(tǒng)?

[2]?知識(shí)科普:IM聊天應(yīng)用是如何將消息發(fā)送給對(duì)方的?(非技術(shù)篇)

[3]?新手入門(mén)一篇就夠:從零開(kāi)發(fā)移動(dòng)端IM

[4]?從客戶(hù)端的角度來(lái)談?wù)勔苿?dòng)端IM的消息可靠性和送達(dá)機(jī)制

[5]?從游擊隊(duì)到正規(guī)軍(二):馬蜂窩旅游網(wǎng)的IM客戶(hù)端架構(gòu)演進(jìn)和實(shí)踐總結(jié)

[6]?談?wù)勔苿?dòng)端 IM 開(kāi)發(fā)中登錄請(qǐng)求的優(yōu)化

[7]?IM開(kāi)發(fā)干貨分享:如何優(yōu)雅的實(shí)現(xiàn)大量離線消息的可靠投遞

[8]?IM開(kāi)發(fā)干貨分享:有贊移動(dòng)端IM的組件化SDK架構(gòu)設(shè)計(jì)實(shí)踐

[9]?IM開(kāi)發(fā)干貨分享:我是如何解決大量離線消息導(dǎo)致客戶(hù)端卡頓的

[10]?阿里技術(shù)分享:閑魚(yú)IM基于Flutter的移動(dòng)端跨端改造實(shí)踐

[11]?IM開(kāi)發(fā)干貨分享:IM客戶(hù)端不同版本兼容運(yùn)行的技術(shù)思路和實(shí)踐總結(jié)

[12]?抖音技術(shù)分享:飛鴿IM桌面端基于Rust語(yǔ)言進(jìn)行重構(gòu)的技術(shù)選型和實(shí)踐總結(jié)

[13]?大型IM工程重構(gòu)實(shí)踐:企業(yè)微信Android端的重構(gòu)之路

[14]?探探的IM長(zhǎng)連接技術(shù)實(shí)踐:技術(shù)選型、架構(gòu)設(shè)計(jì)、性能優(yōu)化

[15]?攜程技術(shù)分享:億級(jí)流量的辦公I(xiàn)M及開(kāi)放平臺(tái)技術(shù)實(shí)踐

[16]?微信團(tuán)隊(duì)分享:來(lái)看看微信十年前的IM消息收發(fā)架構(gòu),你做到了嗎

[17]?一套億級(jí)用戶(hù)的IM架構(gòu)技術(shù)干貨(上篇):整體架構(gòu)、服務(wù)拆分等

[18]?從新手到專(zhuān)家:如何設(shè)計(jì)一套億級(jí)消息量的分布式IM系統(tǒng)

[19]?企業(yè)微信的IM架構(gòu)設(shè)計(jì)揭秘:消息模型、萬(wàn)人群、已讀回執(zhí)、消息撤回等

[20]?一套分布式IM即時(shí)通訊系統(tǒng)的技術(shù)選型和架構(gòu)設(shè)計(jì)

13、百度的其它技術(shù)分享

百度APP移動(dòng)端網(wǎng)絡(luò)深度優(yōu)化實(shí)踐分享(一):DNS優(yōu)化篇

百度APP移動(dòng)端網(wǎng)絡(luò)深度優(yōu)化實(shí)踐分享(二):網(wǎng)絡(luò)連接優(yōu)化篇

百度APP移動(dòng)端網(wǎng)絡(luò)深度優(yōu)化實(shí)踐分享(三):移動(dòng)端弱網(wǎng)優(yōu)化篇

全面了解移動(dòng)端DNS域名劫持等雜癥:原理、根源、HttpDNS解決方案等

深入了解百度開(kāi)源的分布式RPC框架brpc的方方面面

直播系統(tǒng)聊天技術(shù)(四):百度直播的海量用戶(hù)實(shí)時(shí)消息系統(tǒng)架構(gòu)演進(jìn)實(shí)踐

IM消息ID技術(shù)專(zhuān)題(五):開(kāi)源分布式ID生成器UidGenerator的技術(shù)實(shí)現(xiàn)

百度統(tǒng)一socket長(zhǎng)連接組件從0到1的技術(shù)實(shí)踐

百度網(wǎng)盤(pán)千萬(wàn)節(jié)點(diǎn)的P2P架構(gòu)設(shè)計(jì)(PPT) [附件下載]

即時(shí)通訊音視頻開(kāi)發(fā)(二十):一文讀懂視頻的顏色模型轉(zhuǎn)換和色域轉(zhuǎn)換

揭秘百度IM消息中臺(tái)的全量用戶(hù)消息推送技術(shù)改造實(shí)踐

百度基于金融場(chǎng)景構(gòu)建高實(shí)時(shí)、高可用的分布式數(shù)據(jù)傳輸系統(tǒng)的技術(shù)實(shí)踐

長(zhǎng)連接網(wǎng)關(guān)技術(shù)專(zhuān)題(十):百度基于Go的千萬(wàn)級(jí)統(tǒng)一長(zhǎng)連接服務(wù)架構(gòu)實(shí)踐

(本文已同步發(fā)布于:http://www.52im.net/thread-4707-1-1.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容