<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jack Jiang

    我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
    posts - 494, comments - 13, trackbacks - 0, articles - 1

    1、引言

    IM系統中,特別是在企業應用場景下,消息的已讀未讀狀態是一個強需求。

    以阿里的釘釘為例,釘釘的產品定位是用于商務交流,其“強制已讀回執”功能,讓職場人無法再“假裝不在線”、“假裝沒收到”。更有甚者,釘釘的群聊“強制已讀回執”功能,甚至能夠知道誰讀了消息,誰沒有讀消息(老板的福音啊)。

     

    ▲ 釘釘里的群聊消息已讀未讀功能效果

    功能看起來很酷,但用起來是一言難盡(上班族心里苦.... )。實際上,技術實現也并不容易。

    那么,對于已讀未讀狀態:

    • 1)如果是私聊:消息的閱讀狀態比較容易實現,在性能和存儲上也不存在問題;
    • 2)如果是群聊:考慮到存儲和處理性能,特別當處于一個云環境時,如何高效地處理群聊的已讀未讀狀態是一個非常值得探討的話題。

    這里提到的“高效”含3個方面:

    • 1)存儲空間;
    • 2)處理速度;
    • 3)傳輸字節數。

    本文將從服務端的角度來探討已讀未讀狀態,在具體的技術實現上對于存儲空間占用方面的思路差異。能力有限,權當個人筆記,歡迎交流。

    學習交流:

    - 即時通訊/推送技術開發交流5群:215477170[推薦]

    - 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

    本文已同步發布于“即時通訊技術圈”公眾號,歡迎關注:

    ▲ 本文在公眾號上的鏈接是:https://mp.weixin.qq.com/s/yUkKPOBsdqLlxiFrGmwFRQ,原文鏈接是:http://www.52im.net/thread-3054-1-1.html

    2、內容點評

    在收錄本文前,Jack Jiang建議原作者對某些具體的技術點進行更深入的分享,但因作者工作較忙,本文中的某些關鍵技術點未來的及作進一步展開。

    所以,本文可以作為IM聊天消息(主要是群聊)中已讀未讀功能的基本實現思路方面的參考,但不建議盲目迷信文中的結論或方案,避免被一些不夠具體的技術指標而誤導。

    3、相關文章

    如果你還想了解更多有關IM群聊中已讀未讀功能的實現邏輯,可以進一步閱讀干貨文章《IM群聊消息的已讀回執功能該怎么實現?》(強烈推薦)。

    如果你對IM中的已讀未讀功能有產品方面的痛點困惑,可以參考一下微信對已讀未讀功能的設計定位,詳見《IM熱門功能思考:為什么微信里沒有消息“已讀”功能?》。

    更多IM群聊技術方面的文章詳見文本附錄部分。

    4、已讀未讀狀態交互流程

    發送者發送的IM聊天消息,在接收者閱讀消息后,是否要求閱讀者通知已讀,可能是由系統配置、組織配置、群組配置等決定,也可能由發送者根據業務需求決定。以下的討論,均假設消息需要已讀未讀狀態。

    客戶端與服務端之間,關于閱讀狀態的命令只需3個,每個命令含請求和應答。

    4.1 通知消息已讀(私聊、群聊通用)

    當小寶閱讀了一條或若干條消息,需向服務端發送消息已讀通知:“眾愛卿發的x+y+z消息,朕已閱”。

    服務端收到小寶的已讀通知時,需完成以下事項:

    • 1)存儲消息的已讀狀態;
    • 2)返回應答給小寶;
    • 3)向已讀列表的消息的原始發送者通知消息已讀。

    對于第“3)”步:

    • 1)私聊的場合,比較好理解,就是發送給私聊的對方;
    • 2)群聊的場合,可很不一樣:因為小寶發送的已讀消息列表,可能是由眾愛卿發送的。考慮這種假設:張三、李四、王五發出的群聊消息,被小寶一下都閱讀了,那么小寶發出的已讀通知包含的消息列表,需要被IMS分解成3個已讀通知(3個不同的消息列表),分別通知給張三、李四、王五,通知內容是“愛卿(不含'"眾")發的這些消息,朕已閱”。

    下面是大致的邏輯流程圖: 

    4.2 查詢消息的未讀人數(私聊、群聊通用)

    消息的發送者,加載消息列表到聊天窗口時,可能需要展示消息是否被已讀。

    對群聊而言,顯示的信息可能是n人未讀的提示,那么需要向服務端查詢消息的未讀人數,由于客戶端可能在UI顯示自己發出的多條消息,需支持一次請求查詢多條消息。

    以未讀人數的方式來表示消息的閱讀狀態,統一了私聊、群聊的查詢,使得客戶端-服務端間的接口更簡單,同時使客戶端的實現邏輯更統一。

    就像下面這樣:

    • 1)對于私聊:如果未讀人數n>0,表示消息未讀;
    • 2)對于群聊:直接顯示n人未讀即可,當然,當n等于0時表示全部已讀。

    4.3 查詢群消息的已讀、未讀人員清單(群聊)

    當客戶端希望顯示某一條群聊消息的已讀、未讀人員列表,需向服務端發起查詢。

    大致的邏輯流程圖如下:

    5、幾種具體的已讀未讀狀態存儲思路探討

    5.1 基本約定

    群聊的閱讀狀態比私聊復雜,因此這里著重討論群聊的閱讀狀態。

    假設群成員數是n,各個客戶端立即IM服務端發送已讀通知。服務端需存儲每個人的閱讀狀態,包括那些未讀的成員。由于群的成員清單可能變化,比如今天增加了一個成員,則昨天發的消息、與今天發的消息,其接收者列表不一樣。

    即:

    • 1)同一個群的不同消息,對應的接收者列表可能不一樣。
    • 2)換言之,每一條消息都需要記錄完整的接收者列表和已讀人員列表。

    為了方便討論,本章假設群成員有640人為前提。

    5.2 存儲思路1

    每一條消息都維護:

    • 1)接收人員列表receiver_list;
    • 2)已讀人員列表read_list。

    具體是:

    • 1)IM Server收到一條消息時,用全體群成員構建receiver_list;
    • 2)IM Server收到群成員對這條消息的已讀通知時,將此成員加入到read_list。

    客戶端獲取此消息的數據:

    • 1)當需要獲取未讀人數時,用receiver_list的個數減去read_list的個數;
    • 2)當需要獲取已讀、未讀人員列表時,需用receiver_list減去read_list得到未讀人員列表。

    那么,思路1每條消息的存儲空間是:

    640個ID + 不定數量的已讀人員ID

    5.3 存儲思路2

    每一條消息維護:

    • 1)未讀人員列表unread_list;
    • 2)已讀人員列表read_list。

    具體是:

    • 1)IM Server收到一條消息時,用全體群成員構建unread_list;
    • 2)IM Server收到群成員對這條消息的已讀通知時,將此成員從unread_list移出,同時加入到read_list。

    客戶端獲取此消息的數據:

    • 1)當需要獲取未讀人數時,直接計算unread_list的個數;
    • 2)當需要獲取已讀、未讀人員列表時,直接返回unread_list和read_list。

    那么,思路2每條消息的存儲空間是:

    未讀人員ID + 已讀人員ID,合計640個ID

    思路2的實現,占用的空間是案1的0.5倍~1.0倍。即案2占用的空間少,但在每次收到客戶端的已讀通知時,比案1多了一個操作:從unread_list進行減員。

    5.4 存儲思路3(我的實現)

    5.4.1)探討5.2節、5.3節的不足:

    5.2節、5.3節這兩種思路,都能滿足功能需求,但存在巨大的存儲浪費。

    該群有640人,如果群內聊天每天有1024條消息,人員ID以4字節存儲計算,那么為該群每天的消息閱讀狀態需要消耗的空間是:

    5.2節思路1:1024 * (640 * 4 + 已讀人數 * 4),范圍是 2.5MB ~ 5MB;

    5.3節思路2:1024 * 640 * 4,等于2.5MB。

    這僅僅是一個群在一天之內產生的閱讀狀態數據,如果是在云平臺運行,單此功能消耗的空間,呵呵~~

    題外話:如果成員不是用4字節整型存儲,而改用字符串,比如"1123356777",那就更可觀了。

    5.4.2)如何減少存儲空間:

    考慮群成員并非時時刻刻都在變化,多數情況下,群成員的列表是相對穩定的,今天的和上周(甚至更久以前)的列表甚至可能是一樣的,那么有可能幾百條消息,甚至幾萬條消息對應的群成員列表是相同的。

    因此,引出本文的重點思想:

    考慮讓不同的消息共用群成員列表,即把消息的閱讀狀態與群成員列表分開存儲,并記錄它們之間的關聯。

    假定平均每1024條消息共用一個群成員列表,發了1024條消息后,群成員變化了,此后需要用新的群成員列表。

    那么這一千條消息的閱讀狀態所占用的空間是:

    群成員列表空間 + 1024條消息的閱讀狀態:640 * 4 + 1024 * 每條消息的閱讀狀態所占空間

    在具備群成員列表的前提下,如何減少每條消息的閱讀狀態所占空間?

    很自然會想到用bit來表示已讀人員,因為一個32位整型可表示32個人的已讀狀態。bit的順序只需與群成員列表的順序一致即可。

    當一條消息沒有人已讀時,閱讀狀態占用0字節;當群內每個人都閱讀時,占用的空間最大,即640 / 32 = 20字節。

    因此優化之后,這一千條消息的閱讀狀態所占用的空間,范圍是2.5KB ~ (2.5KB + 1024 * 20B),即2.5KB ~ 22.5KB,此數值與5.2節思路1、5.3節思路2對比,有了極大幅度地下降。

    如下圖所示:

    該表格的前提條件:

    • 1)一個群有640人;
    • 2)該群連續1024條消息對應的群成員列表是穩定的。

    退一步考慮,哪怕這1024條消息對應的群成員列表不穩定,中間變化了10次,那么也僅會多出2.5KB * 10即25KB的存儲空間,與案1、案2相比仍然有極大優勢。

    6、如何提高已讀未讀狀態的處理速度

    小寶往公司群發了一條消息我來給大家介紹一下新來的女同事,大家立即、馬上、瞬間、閃電般地查看消息,感覺遲1秒就會失去秒殺女神的機會一樣,意味著一瞬間會有N多條已讀通知發送到IMS。

    對這些消息的處理流程是一樣的:

    • 1)可合并這些操作以批量形式進行存儲、轉發;
    • 2)由于存儲消息的閱讀狀態是一個設置bit的過程,所以不存在互斥的問題,即使在分布式環境也可以放心操作;
    • 3)消息對應的成員列表信息可臨時緩存在內存對象內,以減少查詢IO,提高效率。

    附錄:更多IM群聊技術文章

    快速裂變:見證微信強大后臺架構從0到1的演進歷程(一)

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

    IM單聊和群聊中的在線狀態同步應該用“推”還是“拉”?

    IM群聊消息如此復雜,如何保證不丟不重?

    微信后臺團隊:微信后臺異步消息隊列的優化升級實踐分享

    移動端IM中大規模群消息的推送如何保證效率、實時性?

    現代IM系統中聊天消息的同步和存儲方案探討

    關于IM即時通訊群聊消息的亂序問題討論

    IM群聊消息的已讀回執功能該怎么實現?

    IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?

    一套高可用、易伸縮、高并發的IM群聊、單聊架構方案設計實踐

    [技術腦洞] 如果把14億中國人拉到一個微信群里技術上能實現嗎?

    IM群聊機制,除了循環去發消息還有什么方式?如何優化?

    網易云信技術分享:IM中的萬人群聊技術方案實踐總結

    阿里釘釘技術分享:企業級IM王者——釘釘在后端架構上的過人之處

    IM群聊消息的已讀未讀功能在存儲空間方面的實現思路探討

    >> 更多同類文章 ……

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



    作者:Jack Jiang (點擊作者姓名進入Github)
    出處:http://www.52im.net/space-uid-1.html
    交流:歡迎加入即時通訊開發交流群 215891622
    討論:http://www.52im.net/
    Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
    本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: 色偷偷噜噜噜亚洲男人| 亚洲中文字幕无码一去台湾 | 亚洲欧美日韩国产成人| 2021精品国产品免费观看| 亚洲国产综合精品中文第一区| 日本高清免费观看| 精品亚洲永久免费精品| 中文字幕免费不卡二区 | 亚洲免费在线视频播放| 免费人成网站在线观看10分钟| 亚洲人成毛片线播放| 中文字幕无码免费久久99| 亚洲熟妇无码一区二区三区| 免费无码又爽又刺激高潮 | 亚洲精品无码av片| 在线a亚洲v天堂网2018| 亚欧洲精品在线视频免费观看 | 久久99亚洲综合精品首页| 久久最新免费视频| 91亚洲国产在人线播放午夜| 国产精品成人免费福利| 亚洲AV无码一区二区三区牲色| 免费a级毛片网站| 国产啪精品视频网站免费尤物| 亚洲精品熟女国产| 国产成人涩涩涩视频在线观看免费| 五月婷婷免费视频| 亚洲午夜久久影院| 免费毛片在线播放| 两个人www免费高清视频| 亚洲欧洲日本国产| xvideos亚洲永久网址| 国产精品免费观看调教网| 久久国产亚洲精品| 亚洲天堂在线视频| 91香蕉成人免费网站| 欧美激情综合亚洲一二区| 亚洲av无码片在线播放| 免费黄色毛片视频| 久久国产精品免费视频| 国产亚洲综合视频|