<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] > [參考](https://www.w3cschool.cn/architectroad/architectroad-the-reliable-delivery-of-instant-messaging.html) ## 一、報文類型 im的客戶端與服務器通過發送報文(也就是網絡包)來完成消息的傳遞,報文分為三種 請求報文(request,后簡稱為為R) 應答報文(acknowledge,后簡稱為A) 通知報文(notify,后簡稱為N),這三種報文的解釋如下: ![UTOOLS1576158515021.png](http://yanxuan.nosdn.127.net/89498b7541abdae6dd2109033613b040.png) **R**:客戶端主動發送給服務器的報文 **A**:服務器被動應答客戶端的報文,一個A對應一個R **N**:服務器主動發送給客戶端的報文 ## 二、普通消息投遞流程 用戶A給用戶B發送一個“你好”,流程如下: ![UTOOLS1576158729299.png](http://yanxuan.nosdn.127.net/ecf2bdf32cd1d495426881ac03e634d0.png) 1)client-A向im-server發送一個消息請求包,即msg:R 2)im-server在成功處理后,回復client-A一個消息響應包,即msg:A 3)如果此時client-B在線,則im-server主動向client-B發送一個消息通知包,即 msg:N(當然,如果client-B不在線,則消息會存儲離線) ## 三、上述消息投遞流程出現的問題 從流程圖中容易看到,發送方client-A收到msg:A后,只能說明im-server成功接收到了消息,并不能說明client-B接收到了消息。在若干場景下,可能出現msg:N包丟失,且發送方client-A完全不知道,例如: 1)服務器崩潰,msg:N包未發出 2)網絡抖動,msg:N包被網絡設備丟棄 3)client-B崩潰,msg:N包未接收 結論是悲觀的:**接收方client-B是否有收到msg:N,發送方client-A完全不可控,那怎么辦呢?** ## 四、應用層確認+im消息可靠投遞的六個報文 upd是一種不可靠的傳輸層協議,tcp是一種可靠的傳輸層協議,tcp是如何做到可靠的?答案是:超時、重傳、確認。 要想實現應用層的消息可靠投遞,必須加入應用層的確認機制,即:要想讓發送方client-A確保接收方client-B收到了消息,必須讓接收方client-B給一個消息的確認,這個應用層的確認的流程,與消息的發送流程類似: ![UTOOLS1576158670370.png](http://yanxuan.nosdn.127.net/4bc67226f7c0178340429cd1618dc3e7.png) 4)client-B向im-server發送一個ack請求包,即ack:R 5)im-server在成功處理后,回復client-B一個ack響應包,即ack:A 6)則im-server主動向client-A發送一個ack通知包,即ack:N 至此,發送“你好”的client-A,在收到了ack:N報文后,才能確認client-B真正接收到了“你好”。 會發現,一條消息的發送,分別包含(上)(下)兩個半場,即msg的R/A/N三個報文,ack的R/A/N三個報文,一個應用層即時通訊消息的可靠投遞,共涉及6個報文,這就是im系統中消息投遞的最核心技術。 ## 五、可靠消息投遞存在什么問題 期望六個報文完成消息的可靠投遞,但實際情況,**msg:N,ack:N這兩個報文都可能丟失**(原因如第二章所述,可能是服務器奔潰、網絡抖動、或者客戶端奔潰),此時client-A都收不到期待的ack:N報文,即client-A不能確認client-B是否收到“你好”,但這兩個報文的丟失對應的業務影響又大有不同: 1)msg:N包丟失,業務結果是client-B沒有收到消息 2)ack:N包丟失,業務結果是client-B收到了消息,只是client-A不知道而已 那怎么辦呢? ## 六、消息的超時與重傳 client-A發出了msg:R,收到了msg:A之后,在一個期待的時間內,如果沒有收到ack:N,client-A會嘗試將msg:R重發。可能client-A同時發出了很多消息,故client-A需要在本地維護一個等待ack隊列,并配合timer超時機制,來記錄哪些消息沒有收到ack:N,以定時重發。 ![UTOOLS1576158690529.png](http://yanxuan.nosdn.127.net/cf1e2dbc992b06350a703711b874f2dc.png) 一旦收到了ack:N,說明client-B收到了“你好”消息,對應的消息將從“等待ack隊列”中移除。 ## 七、消息的重傳存在什么問題 第五章提到過,msg:N,ack:N都有可能丟失: 1)msg:N報文丟失,說明client-B之前壓根沒有收到“你好”報文,超時與重傳機制十分有效 2)ack:N報文丟失,說明client-B之前已經收到了“你好”報文(只是client-A不知道而已),超時與重傳機制將導致client-B收到重復的消息,那怎么辦呢? ## 八、消息的去重 解決方法也很簡單,由發送方client-A生成一個消息去重的msgid,保存在“等待ack隊列”里,同一條消息使用相同的msgid來重傳,供client-B去重,而不影響用戶體驗。 ## 九、其他 1)上述設計理念,由客戶端重傳,可以保證服務端無狀態性(架構設計基本準則) 2)如果client-B不在線,im-server保存了離線消息后,要偽造ack:N發送給client-A ## 十、總結 1)**im系統是通過超時、重傳、確認、去重的機制來保證消息的可靠投遞,不丟不重** 2)**一個“你好”的發送,包含上半場msg:R/A/N與下半場ack:R/A/N的6個報文** 3)im系統**難以做到系統層面的不丟不重,只能做到業務層面的不丟不重**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看