日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

IM群聊消息的已读回执功能该怎么实现?

發(fā)布時(shí)間:2023/12/29 综合教程 43 生活家
生活随笔 收集整理的這篇文章主要介紹了 IM群聊消息的已读回执功能该怎么实现? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文引用了架構(gòu)師之路公眾號(hào)作者沈劍的文章,內(nèi)容有改動(dòng),感謝原作者。

1、前言

我們平時(shí)在使用即時(shí)通訊應(yīng)用時(shí)候,每當(dāng)發(fā)出一條聊天消息,都希望對方盡快看到,并盡快回復(fù),但對方到底有沒有真的看到?我卻并不知道。

一個(gè)殘酷的現(xiàn)實(shí)是,很多時(shí)候?qū)Ψ狡鋵?shí)是早就已經(jīng)看到了這條消息,但出出種種原因(大家都懂的),通常都是默默返回——假裝沒看見。

像微信這樣的熟人社交工具,在產(chǎn)品的設(shè)計(jì)理念上,為了保持使用者的隱私性,在線狀態(tài)、已讀回執(zhí)等涉及隱私的功能,都沒有提供。但很多時(shí)候,尤其商務(wù)、辦公場合下,特別需要一種強(qiáng)反饋的工具,這對于打造高效的團(tuán)隊(duì)很有幫助(雖然員工很反感,但老板都喜歡這樣的功能,哈哈)。

目前市面上主流的移動(dòng)端IM里,提供了已讀回執(zhí)的主要有阿里的釘釘、網(wǎng)易的易信、阿里的旺旺,如下圖所示:
<ignore_js_op><ignore_js_op><ignore_js_op>
▲ 上圖從左至右分別為:釘釘、易信、旺旺(千牛)

以阿里的釘釘為例,釘釘?shù)漠a(chǎn)品定位是用于商務(wù)交流,其“強(qiáng)制已讀回執(zhí)”功能,讓職場人無法再“假裝不在線”、“假裝沒收到”。更有甚者,釘釘?shù)娜毫?ldquo;強(qiáng)制已讀回執(zhí)”功能,甚至能夠知道誰讀了消息,誰沒有讀消息(老板的福音啊)。

那么群聊消息的收發(fā)流程、消息的送達(dá)保證、已讀回執(zhí)機(jī)制,到底該怎么實(shí)現(xiàn)呢?這就是今天要討論的話題。

學(xué)習(xí)交流:

- 即時(shí)通訊開發(fā)交流3群:185926912[推薦]

- 移動(dòng)端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動(dòng)端IM》

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

2、IM開發(fā)干貨系列文章


本文是系列文章中的第14篇,總目錄如下:

《IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(一):保證在線實(shí)時(shí)消息的可靠投遞》
《IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(二):保證離線消息的可靠投遞》
《如何保證IM實(shí)時(shí)消息的“時(shí)序性”與“一致性”?》
《IM單聊和群聊中的在線狀態(tài)同步應(yīng)該用“推”還是“拉”?》
《IM群聊消息如此復(fù)雜,如何保證不丟不重?》
《一種Android端IM智能心跳算法的設(shè)計(jì)與實(shí)現(xiàn)探討(含樣例代碼)》
《移動(dòng)端IM登錄時(shí)拉取數(shù)據(jù)如何作到省流量?》
《通俗易懂:基于集群的移動(dòng)端IM接入層負(fù)載均衡方案分享》
《淺談移動(dòng)端IM的多點(diǎn)登陸和消息漫游原理》
《IM開發(fā)基礎(chǔ)知識(shí)補(bǔ)課(一):正確理解前置HTTP SSO單點(diǎn)登陸接口的原理》
《IM開發(fā)基礎(chǔ)知識(shí)補(bǔ)課(二):如何設(shè)計(jì)大量圖片文件的服務(wù)端存儲(chǔ)架構(gòu)?》
《IM開發(fā)基礎(chǔ)知識(shí)補(bǔ)課(三):快速理解服務(wù)端數(shù)據(jù)庫讀寫分離原理及實(shí)踐建議》
《IM開發(fā)基礎(chǔ)知識(shí)補(bǔ)課(四):正確理解HTTP短連接中的Cookie、Session和Token》
《IM群聊消息的已讀回執(zhí)功能該怎么實(shí)現(xiàn)?》(本文)


另外,如果您是IM開發(fā)初學(xué)者,強(qiáng)烈建議首先閱讀《新手入門一篇就夠:從零開發(fā)移動(dòng)端IM》。

3、正文引言


首先我們需要了解一下群消息的設(shè)計(jì)、投遞流程以及可達(dá)性保證機(jī)制,因不是本文要討論的重點(diǎn),所以盡量言簡意賅,更詳細(xì)的資料請見下方的推薦文章列表。

如您對聊天消息的投遞和送達(dá)機(jī)制等尚無概念,可先讀本系列文章的以下幾篇,有助于您詳細(xì)掌握這方面的內(nèi)容:

《IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(一):保證在線實(shí)時(shí)消息的可靠投遞》
《IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(二):保證離線消息的可靠投遞》
《如何保證IM實(shí)時(shí)消息的“時(shí)序性”與“一致性”?》
《IM群聊消息如此復(fù)雜,如何保證不丟不重?》

4、群消息怎么設(shè)計(jì)?


大家一起跟著樓主的節(jié)奏,一步一步來看群消息怎么設(shè)計(jì)。

核心問題1:群消息,只存一份?還是,每個(gè)成員存一份?
答:存一份,為每個(gè)成員設(shè)置一個(gè)群消息隊(duì)列,會(huì)有大量數(shù)據(jù)冗余,并不合適。

核心問題2:如果群消息只存一份,怎么知道每個(gè)成員讀了哪些消息?
答:可以利用群消息的偏序關(guān)系,記錄每個(gè)成員的last_ack_msgid(last_ack_time),這條消息之前的消息已讀,這條消息之后的消息未讀。該方案意味著,對于群內(nèi)的每一個(gè)用戶,只需要記錄一個(gè)值即可。

解答上述兩個(gè)核心問題后,很容易得到群消息的核心數(shù)據(jù)結(jié)構(gòu)。

群消息表:記錄群消息

group_msgs(msgid, gid, sender_uid, time, content);


各字段的含義為:消息ID,群ID,發(fā)送方UID,發(fā)送時(shí)間,發(fā)送內(nèi)容。

群成員表:記錄群里的成員,以及每個(gè)成員收到的最后一條群消息

group_users(gid, uid, last_ack_msgid);


各字段的含義為:群ID,群成員UID,群成員最后收到的一條群消息ID。

5、了解一下群消息發(fā)送的流程


在核心數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)完之后,一起來看看群消息發(fā)送的流程(本系列中的文章《IM群聊消息如此復(fù)雜,如何保證不丟不重?》詳細(xì)講解了這個(gè)過程,可以深入讀一讀)。

業(yè)務(wù)場景:

1)一個(gè)群中有A, uid1, uid2, uid3四名成員;
2)A, uid1, uid2在線,期望實(shí)時(shí)收到在線消息;
3)uid3離線,期望未來拉取到離線消息。


<ignore_js_op>

其整個(gè)消息發(fā)送的流程1-4如上圖:

1)A發(fā)出群消息;
2)server收到消息后,一來要將群消息落地,二來要查詢?nèi)豪镉心男┤撼蓡T,以便實(shí)施推送;
3)對于群成員,查詢在線狀態(tài);
4)對于在線的群成員,實(shí)施推送。


這個(gè)流程里,只要第二步消息落地完成,就能保證群消息不會(huì)丟失。

核心問題3:如何保證接收方一定收到群消息?
答:各個(gè)收到消息后,要修改各群成員的last_ack_msgid,以告訴系統(tǒng),這一條消息確認(rèn)收到了。

在線消息,離線消息的last_ack_msgid的修改,又各有不同。

<ignore_js_op>
對于在線的群友,收到群消息后,第一時(shí)間會(huì)ack、修改last_ack_msgid。

<ignore_js_op>
對于離線的群友,會(huì)在下一次登錄時(shí),拉取未讀的所有群離線消息,并將last_ack_msgid修改為最新的一條消息。

核心問題4:如果ack丟失,群友會(huì)不會(huì)拉取重復(fù)的群消息?
答:會(huì),可以根據(jù)msgid在客戶端本地做去重,即使系統(tǒng)層面收到了重復(fù)的消息,仍然可以保證良好的用戶體驗(yàn)。

上述流程,只能確保接收方收到消息,發(fā)送方仍然不知道哪些人在線閱讀了消息,哪些人離線未閱讀消息,并沒有實(shí)現(xiàn)已讀回執(zhí),那已讀回執(zhí)會(huì)對系統(tǒng)設(shè)計(jì)產(chǎn)生什么樣的影響呢?

6、已讀回執(zhí)流程的設(shè)計(jì)


前面的基礎(chǔ)知識(shí)我們已經(jīng)了解的差不多,本節(jié)來討論本文的重點(diǎn)內(nèi)容,即群聊已讀回執(zhí)流程到底該怎么設(shè)計(jì)。

對于發(fā)送方發(fā)送的任何一條群消息,都需要知道,這條消息有多少人已讀多少人未讀,就需要一個(gè)基礎(chǔ)表來記錄這個(gè)關(guān)系。

消息回執(zhí)表:用來記錄消息的已讀回執(zhí)

msg_acks(sender_uid, msgid, recv_uid, gid,if_ack);


各字段的含義為:發(fā)送方UID,消息ID,回執(zhí)方UID,群ID,回執(zhí)標(biāo)記。

增加了已讀回執(zhí)邏輯后,群消息的流程會(huì)有細(xì)微的改變,見下圖:
<ignore_js_op>

接著,server收到消息后,除了要:

1)將群消息落地;
2)查詢?nèi)豪镉心男┤撼蓡T,以便實(shí)施推送;


之外,還需要:

3)插入每條消息的初始回執(zhí)狀態(tài)。


<ignore_js_op>

接收方修改last_ack_msgid的流程,會(huì)變?yōu)椋?/p>

1)發(fā)送ack請求;
2)修改last_ack_msgid,并且,修改已讀回執(zhí)if_ack狀態(tài);
3)查詢發(fā)送方在線狀態(tài);
4)向發(fā)送方實(shí)時(shí)推送已讀回執(zhí)(如果發(fā)送方在線);


如果發(fā)送方不在線,ta會(huì)在下次登錄的時(shí)候:

5)從關(guān)聯(lián)表里拉取每條消息的已讀回執(zhí)。


這里的初步結(jié)論是:

如果發(fā)送方在線:會(huì)實(shí)時(shí)被推送已讀回執(zhí);
如果發(fā)送方不在線:會(huì)在下次在線時(shí)拉取已讀回執(zhí)。

7、已讀回執(zhí)流程優(yōu)化方案


再次詳細(xì)的分析下,群消息已讀回執(zhí)的“消息風(fēng)暴擴(kuò)散系數(shù)”,假設(shè)每個(gè)群有200個(gè)用戶,其中20%的用戶在線,即40各用戶在線。

那么,群用戶每發(fā)送一條群消息,會(huì)有:

40個(gè)消息,通知給群友;
40個(gè)ack修改last_ack_msgid,發(fā)給服務(wù)端;
40個(gè)已讀回執(zhí),通知給發(fā)送方。


可見,其消息風(fēng)暴擴(kuò)散系數(shù)非常之大。

同時(shí):

需要存儲(chǔ)40條ack記錄。


群數(shù)量,群友數(shù)量,群消息數(shù)量越來越多之后,存儲(chǔ)也會(huì)成為問題。

是否有優(yōu)化方案呢?

群消息的推送,能否改為接收方輪詢拉取?
答:不能,消息接收,實(shí)時(shí)性是核心指標(biāo)。

對于last_ack_msgid的修改,真的需要每個(gè)群消息都進(jìn)行ack么?
答:其實(shí)不需要,可以批量ack,累計(jì)收到N條群消息(例如10條),再向服務(wù)器發(fā)送一次last_ack_msgid的修改請求,同時(shí)修改這個(gè)請求之前所有請求的已讀回執(zhí),這樣就能將40個(gè)發(fā)送給服務(wù)端的ack請求量,降為原來的1/10。

會(huì)帶來什么副作用?
答:last_ack_msgid的作用是,記錄接收方最近新取的一條群消息,如果不實(shí)時(shí)更新,可能導(dǎo)致,異常退出時(shí),有一些群消息沒來得及更新last_ack_msgid,使得下次登陸時(shí),會(huì)拉取到重復(fù)的群消息。但這不是問題,客戶端可以根據(jù)msgid去重,用戶體驗(yàn)不會(huì)受影響。

發(fā)送方在線時(shí),對于已讀回執(zhí)的發(fā)送,真的需要實(shí)時(shí)推送么?
答:其實(shí)不需要,發(fā)送方每發(fā)一條消息,會(huì)收到40個(gè)已讀回執(zhí),采用輪詢拉取(例如1分鐘一次,一個(gè)小時(shí)也就60個(gè)請求),可以大大降低請求量。
(畫外音:或者直接放到應(yīng)用層keepalive請求里,做到0額外請求增加。)

會(huì)帶來什么副作用?
答:已讀回執(zhí)更新不實(shí)時(shí),最壞的情況下,1分鐘才更新回執(zhí)。當(dāng)然,可以根據(jù)性能與產(chǎn)品體驗(yàn)來折衷配置這個(gè)輪詢時(shí)間。

如何降低數(shù)據(jù)量?
答:回執(zhí)數(shù)據(jù)不是核心數(shù)據(jù)

已讀的消息,可以進(jìn)行物理刪除,而不是標(biāo)記刪除;
超過N長時(shí)間的回執(zhí),歸檔或者刪除掉。

8、本文小結(jié)


對于群消息已讀回執(zhí),一般來說:

如果發(fā)送方在線,會(huì)實(shí)時(shí)被推送已讀回執(zhí);
如果發(fā)送方不在線,會(huì)在下次在線時(shí)拉取已讀回執(zhí)。


如果要對進(jìn)行優(yōu)化,可以:

接收方累計(jì)收到N條群消息再批量ack;
發(fā)送方輪詢拉取已讀回執(zhí)。


物理刪除已讀回執(zhí)數(shù)據(jù),定時(shí)刪除或歸檔非核心歷史數(shù)據(jù)。

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

總結(jié)

以上是生活随笔為你收集整理的IM群聊消息的已读回执功能该怎么实现?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。