標(biāo)記已讀

單聊

  • 發(fā)送方發(fā)送一條消息
  • 服務(wù)端消息入庫(kù),檢查接收方在線狀態(tài)。若在線,推送;不在線,接收方登錄時(shí)拉取
  • 接收方收到消息,發(fā)送已讀回執(zhí)
  • 服務(wù)端收到回執(zhí)并入庫(kù),通知發(fā)送方
  • 發(fā)送方更新本地?cái)?shù)據(jù)庫(kù),修改已讀狀態(tài)

群聊

群消息投遞流程,以及可達(dá)性保證

核心問(wèn)題
  • 群消息,只存一份?還是,每個(gè)成員存一份?
    存一份
  • 如果群消息只存一份,怎么知道每個(gè)成員讀了哪些消息?
    記錄每個(gè)成員的last_ack_msgid
  • 如何保證接收方一定收到群消息?
    各個(gè)群成員收到消息后,要修改各群成員的last_ack_msgid,以告訴系統(tǒng),這一條消息確認(rèn)收到了
  • 如果ack丟失,群友會(huì)不會(huì)拉取重復(fù)的群消息?
    會(huì),可以根據(jù)msgid在客戶端本地做去重
核心數(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。
群消息發(fā)送的流程
群消息發(fā)送的流程
  • A發(fā)出群消息
  • server收到消息后,一來(lái)要將群消息落地,二來(lái)要查詢?nèi)豪镉心男┤撼蓡T,以便實(shí)施推送
  • 對(duì)于群成員,查詢?cè)诰€狀態(tài)
  • 對(duì)于在線的群成員,實(shí)施推送
群消息確認(rèn)流程
在線成員

離線成員

已讀回執(zhí)流程

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

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

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

群消息流程
消息流程
  • 將群消息入庫(kù)
  • 查詢?nèi)豪镉心男┤撼蓡T,以便實(shí)施推送
  • 插入每條消息的初始回執(zhí)狀態(tài)


    發(fā)送方已讀回執(zhí)
  • 發(fā)送ack請(qǐng)求
  • 修改last_ack_msgid,并且,修改已讀回執(zhí)if_ack狀態(tài)
  • 查詢發(fā)送方在線狀態(tài)
  • 向發(fā)送方實(shí)時(shí)推送已讀回執(zhí)(如果發(fā)送方在線)
  • 如果發(fā)送方不在線,ta會(huì)在下次登錄的時(shí)候,從關(guān)聯(lián)表里拉取每條消息的已讀回執(zhí)

流程優(yōu)化方案

群消息已讀回執(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ā)送方
  • 需要存儲(chǔ)40條ack記錄
優(yōu)化方案
  • 群消息的推送,能否改為接收方輪詢拉?。?br> 答:不能,消息接收,實(shí)時(shí)性是核心指標(biāo)。
  • 對(duì)于last_ack_msgid的修改,真的需要每個(gè)群消息都進(jìn)行ack么?
    答:其實(shí)不需要,可以批量ack。有副作用(不實(shí)時(shí),拉取重復(fù)消息)
  • 發(fā)送方在線時(shí),對(duì)于已讀回執(zhí)的發(fā)送,真的需要實(shí)時(shí)推送么?
    答:其實(shí)不需要,發(fā)送方每發(fā)一條消息,會(huì)收到40個(gè)已讀回執(zhí),采用輪詢拉取或放入keepalive請(qǐng)求里。副作用是不實(shí)時(shí)。

原文:https://mp.weixin.qq.com/s/fQhmrrJ0jypm_O3WFs7ftw

最后編輯于
?著作權(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ù)。

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