Jack Jiang

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

               摘要: 本文由微信開發團隊工程師“virwu”分享。1、引言近期,微信小游戲支持了視頻號一鍵開播,將微信升級到最新版本,打開騰訊系小游戲(如跳一跳、歡樂斗地主等),在右上角菜單就可以看到發起直播的按鈕一鍵成為游戲主播了(如下圖所示)。然而微信小游戲出于性能和安全等一系列考慮,運行在一個獨立的進程中,在該環境中不會初始化視頻號直播相關的模塊。這就意味著小游戲的音視頻數據必須跨進程傳輸...  閱讀全文

          posted @ 2021-06-21 15:32 Jack Jiang 閱讀(175) | 評論 (0)編輯 收藏

          本文引用了“拍樂云Pano”的“深入淺出理解視頻編解碼技術”和“揭秘視頻千倍壓縮背后的技術原理之預測技術”文章部分內容,感謝原作者的分享。

          1、引言

          從 20 世紀 90 年代以來,數字音視頻編解碼技術迅速發展,一直是國內外研究的熱點領域。隨著5G的成熟和廣泛商用,帶寬已經越來越高,傳輸音視頻變得更加容易。視頻直播、視頻聊天,已經完全融入了每個人的生活。

          視頻為何如此普及呢?是因為通過視頻能方便快捷地獲取到大量信息。但視頻數據量非常巨大,視頻的網絡傳輸也面臨著巨大的挑戰。于是視頻編解碼技術就出場了。

          具體到實時視頻場景,不僅僅是數據量的問題,實時通信對時延要求、設備適配、帶寬適應的要求也非常高,要解決這些問題,始終離不開視頻編解碼技術的范疇。

          本文將從視頻編解碼技術的基礎知識入手,引出視頻編解碼技術中非常基礎且重要的預測技術,學習幀內預測和幀間預測的技術原理。

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

          2、相關文章

          如果你是音視頻技術初學者,以下3篇入門級干貨非常推薦一讀:

          零基礎,史上最通俗視頻編碼技術入門

          零基礎入門:實時音視頻技術基礎知識全面盤點

          實時音視頻面視必備:快速掌握11個視頻技術相關的基礎概念

          3、為什么需要視頻編解碼

          首先,來復習一下視頻編解碼方面的理論常識。

          視頻是由一系列圖片按照時間順序排列而成:

          • 1)每一張圖片為一幀;
          • 2)每一幀可以理解為一個二維矩陣;
          • 3)矩陣的每個元素為一個像素。

          一個像素通常由三個顏色進行表達,例如用RGB顏色空間表示時,每一個像素由三個顏色分量組成。每一個顏色分量用1個字節來表達,其取值范圍就是0~255。編碼中常用的YUV格式與之類似,這里不作展開。

          1280x720@60fps的視頻序列為例,十秒鐘的視頻有:1280*720*3*60*10 = 1.6GB

          如此大量的數據,無論是存儲還是傳輸,都面臨巨大的挑戰。視頻壓縮或者編碼的目的,也是為了保證視頻質量的前提下,將視頻減小,以利于傳輸和存儲。同時,為了能正確還原視頻,需要將其解碼。

          PS:限于篇幅,視頻編解碼方面的技術原理就不在此展開,有興趣強烈推薦從這篇深入學習:即時通訊音視頻開發(十九):零基礎,史上最通俗視頻編碼技術入門》。

          總之,視頻編解碼技術的主要作用就是:在可用的計算資源內,追求盡可能高的視頻重建質量和盡可能高的壓縮比,以達到帶寬和存儲容量的要求。

          為何突出“重建質量”?

          因為視頻編碼是個有損的過程,用戶只能從收到的視頻流中解析出“重建”畫面,它與原始的畫面已經不同,例如觀看低質量視頻時經常會碰到的“塊”效應。

          如何在一定的帶寬占用下,盡可能地保持視頻的質量,或者在保持質量情況下,盡可能地減少帶寬利用率,是視頻編碼的基本目標。

          用專業術語來說,即視頻編解碼標準的“率失真”性能:

          • 1)“率”是指碼率或者帶寬占用;
          • 2)“失真”是用來描述重建視頻的質量。

          與編碼相對應的是解碼或者解壓縮過程,是將接收到的或者已經存儲在介質上的壓縮碼流重建成視頻信號,然后在各種設備上進行顯示。

          4、什么是視頻編解碼標準

          視頻編解碼標準,通常只定義上述的解碼過程。

          例如 H.264 / AVC 標準,它定義了什么是符合標準的視頻流,對每一個比特的順序和意義都進行了嚴格地定義,對如何使用每個比特或者幾個比特表達的信息也有精確的定義。

          正是這樣的嚴格和精確,保證了不同廠商的視頻相關服務,可以很方便地兼容在一起,例如用 iPhone、Android Phone 或者 windows PC 都可以觀看同一在線視頻網站的同一視頻。

          世界上有多個組織進行視頻編碼標準的制定工作,國際標準組織 ISO 的 MPEG 小組、國際電信聯盟 ITU-T 的 VCEG 小組、中國的 AVS 工作組、Google 及各大廠商組成的開放媒體聯盟等。

          視頻編碼標準及發展歷史:

          自 VCEG 制定 H.120標準開始,視頻編碼技術不斷發展,先后成功地制定了一系列滿足不同應用場景的視頻編碼標準。VCEG 組織先后制定了H.120、H.261、H.262(MPEG-2 Part 2)、H.263、H.263+、H.263++

          MPEG也先后制定了MPEG-1、MPEG-2、MPEG-4 Part 2。以及兩個國際組織合作制定的H.264/AVC、H.265/HEVC、H.266/VVC

          中國自主知識產權的 AVS、AVS2、AVS3 視頻編碼標準;Google 制定的 VP8、VP9。

          Google、思科、微軟、蘋果等公司組成的開放媒體聯盟(AOM)制定的 AV1。

          這里特別提一下H.264/AVC:H.264/AVC雖有近20年歷史,但它優秀的壓縮性能、適當的運算復雜度、優秀的開源社區支持、友好的專利政策、強大的生態圈等多個方面的因素,依舊讓它保持著強大的生命力,特別是在實時通信領域。像 ZOOM、思科 Webex 等視頻會議產品和基于 WebRTC SDK 的視頻服務,大多數主流場景都采用 H.264/AVC。

          有關視頻編解碼標準,這里就不深入展開。更多詳細資料,可以讀一下下面這些精選文章:

          即時通訊音視頻開發(五):認識主流視頻編碼技術H.264

          即時通訊音視頻開發(十三):實時視頻編碼H.264的特點與優勢

          即時通訊音視頻開發(十七):視頻編碼H.264、VP8的前世今生

          愛奇藝技術分享:輕松詼諧,講解視頻編解碼技術的過去、現在和將來

          5、混和編碼框架

          縱觀視頻編解碼標準歷史,每一代視頻標準都在率失真性能上有著顯著的提升,他們都有一個核心的框架,就是基于塊的混合編碼框架(如下圖所示)。它是由J. R. Jain 和A. K. Jain在1979年的國際圖像編碼學會(PCS 1979)上提出了基于塊運動補償和變換編碼的混合編碼框架。

          我們一起來對該框架進行拆解和分析。

          從攝像頭采集到的一幀視頻:通常是 YUV 格式的原始數據,我們將它劃分成多個方形的像素塊依次進行處理(例如 H.264/AVC 中以16x16像素為基本單元),進行幀內/幀間預測、正變換、量化、反量化、反變換、環路濾波、熵編碼,最后得到視頻碼流。從視頻第一幀的第一個塊開始進行空間預測,因當前正在進行編碼處理的圖像塊和其周圍的圖像塊有相似性,我們可以用周圍的像素來預測當前的像素。我們將原始像素減去預測像素得到預測殘差,再將預測殘差進行變換、量化,得到變換系數,然后將其進行熵編碼后得到視頻碼流。

          接下來:為了可以使后續的圖像塊可以使用已經編碼過的塊進行預測,我們還要對變換系統進行反量化、反變換,得到重建殘差,再與預測值進行求合,得到重建圖像。最后我們對重建圖像進行環路濾波、去除塊效應等,這樣得到的重建圖像,就可以用來對后續圖像塊進行預測了。按照以上步驟,我們依次對后續圖像塊進行處理。

          對于視頻而言:視頻幀與幀的間隔大約只有十到幾十毫秒,通常拍攝的內容不會發生劇烈變化,它們之間存在非常強的相關性。

          如下圖所示,將視頻圖像分割成塊,在時間相鄰的圖像之間進行匹配,然后將匹配之后的殘差部分進行編碼,這樣可以較好地去除視頻信號中的視頻幀與幀之間的冗余,達到視頻壓縮的目的。這就是運動補償技術,直到今天它仍然是視頻編解碼的核心技術之一。

          運動估計和運動補償:

          變換編碼的核心思想:是把視頻數據分割成塊,利用正交變換將數據的能量集中到較少幾個變換系數上。結合量化和熵編碼,我們可以獲得更有效的壓縮。視頻編碼中信息的損失和壓縮比的獲得,很大程度上來源于量化模塊,就是將源信號中的單一樣本映射到某一固定值,形成多到少的映射,從而達到壓縮的目的,當然在壓縮的過程中就引入了損失。量化后的信號再進行無損的熵編碼,消除信號中的統計冗余。熵編碼的研究最早可以追溯到 20 世紀 50 年代,經過幾十年的發展,熵編碼在視頻編碼中的應用更加成熟、更加精巧,充分利用視頻數據中的上下文信息,將概率模型估計得更加準確,從而提高了熵編碼的效率。例如H.264/AVC中的Cavlc(基于上下文的變長編碼)、Cabac(基于上下文的二進制算術編碼)。算術編碼技術在后續的視頻編碼標準,如AV1、HEVC/H.265、VVC/H.266 中也有應用。

          視頻編碼發展至今,VVC/H.266 作為最新制定的標準,采納了一系列先進的技術,對混合編碼框架的各個部分都進行了優化和改進,使得其率失真性能相比前一代標準,又提高了一倍。

          例如:VVC/H.266 采用了128x128大小的基本編碼單元,并且可以繼續進行四叉樹劃分,支持對一個劃分進行二分、三分;色度分量獨立于亮度分量,支持單獨進行劃分;更多更精細的幀內預測方向、幀間預測模式;支持多種尺寸和形式的變換、環內濾波等。

          VVC/H.266 的制定,目標是對多種視頻內容有更好支持,例如屏幕共享內容、游戲、動漫、虛擬現實內容(VR、AR)等。其中也有特定的技術被采納進標準,例如調色板模式、幀內運動補償、仿射變換、跳過變換、自適應顏色變換等。   

          回到本文的正題,接下來的內容,我們著重介紹視頻編解碼中的預測技術。

          6、幀內預測技術

          視頻數據被劃分成方塊之后,相鄰的方塊的像素,以及方塊內的像素,顏色往往是逐漸變化的,他們之間有比較強的有相似性。這種相似性,就是空間冗余。既然存在冗余,就可以用更少的數據量來表達這樣的特征。

          比如:先傳輸第一個像素的值,再傳輸第二個像素相對于第一個像素的變化值,這個變化值往往取值范圍變小了許多,原來要8個bit來表達的像素值,可能只需要少于8個bit就足夠了。

          同樣的道理,以像素塊為基本單位,也可以進行類似的“差分”操作。我們從示例圖中,來更加直觀地感受一下這樣的相似性。

          如上圖中所標出的兩個8x8的塊:其亮度分量(Y)沿著“左上到右下”的方向,具有連續性,變化不大。

          假如:我們設計某種特定的“模式”,使其利用左邊的塊來“預測”右邊的塊,那么“原始像素”減去“預測像素”就可以減少傳輸所需要的數據量,同時將該“模式”寫入最終的碼流,解碼器便可以利用左側的塊來“重建”右側的塊。

          極端一點講:假如左側的塊的像素值經過一定的運算可以完全和右側的塊相同,那么編碼器只要用一個“模式”的代價,傳輸右側的塊。

          當然,視頻中的紋理多種多樣,單一的模式很難對所有的紋理都適用,因此標準中也設計了多種多樣的幀內預測模式,以充分利用像素間的相關性,達到壓縮的目的。

          例如下圖所示的H.264中9種幀內預測方向:以模式0(豎直預測)為例,上方塊的每個像素值(重建)各復制一列,得到幀內預測值。其它各種模式也采用類似的方法,不過,生成預測值的方式稍有不同。有這么多的模式,就產生了一個問題,對于一個塊而言,我們應該采用哪種模式來進行編碼呢?最佳的選擇方式,就是遍歷所有的模式進行嘗試,計算其編碼的所需的比特數和產生的質量損失,即率失真優化,這樣明顯非常復雜,因而也有很多種其它的方式來推斷哪種模式更好,例如基于SATD或者邊緣檢測等。

          從H.264的9種預測模式,到AV1的56種幀內方向預測模式,越來越多的模式也是為了更加精準地預測未編碼的塊,但是模式的增加,一方面增加了傳輸模式的碼率開銷,另一方面,從如此重多的模式中選一個最優的模式來編碼,使其能達到更高的壓縮比,這對編碼器的設計和實現也提出了更高的要求。

          7、幀間預測技術

          以下5張圖片是一段視頻的前5幀:可以看出,圖片中只有Mario和磚塊在運動,其余的場景大多是相似的,這種相似性就稱之為時間冗余。編碼的時候,我們先將第一幀圖片通過前文所述的幀內預測方式進行編碼傳輸,再將后續幀的Mario、磚塊的運動方向進行傳輸,解碼的時候,就可以將運動信息和第一幀一起來合成后續的幀,這樣就大大減少了傳輸所需的bit數。這種利用時間冗余來進行壓縮的技術,就是運動補償技術。該技術早在H.261標準中,就已經被采用。

          細心地讀者可能已經發現:Mario和磚塊這樣的物體怎么描述,才能讓它僅憑運動信息就能完整地呈現出來?

          其實視頻編碼中并不需要知道運動的物體的形狀,而是將整幀圖像劃分成像素塊,每個像素塊使用一個運動信息。即基于塊的運動補償。

          下圖中紅色圈出的白色箭頭即編碼磚塊和Mario時的運動信息,它們都指向了前一幀中所在的位置。Mario和磚塊都有兩個箭頭,說明它們都被劃分在了兩個塊中,每一個塊都有單獨的運動信息。這些運動信息就是運動矢量。運動矢量有水平和豎直兩個分量,代表是的一個塊相對于其參考幀的位置變化。參考幀就是已經編碼過的某一(多)個幀。

          當然:傳輸運動矢量本身就要占用很多 bit。為了提高運動矢量的傳輸效率,主要有以下措施。

          一方面:可以盡可能得將塊劃分變大,共用一個運動矢量,因為平坦區域或者較大的物體,他們的運動可能是比較一致的。從 H.264 開始,可變塊大小的運動補償技術被廣泛采用。

          另一方面:相鄰的塊之間的運動往往也有比較高的相似性,其運動矢量也有較高的相似性,運動矢量本身也可以根據相鄰的塊運動矢量來進行預測,即運動矢量預測技術;

          最后:運動矢量在表達物體運動的時候,有精度的取舍。像素是離散化的表達,現實中物體的運動顯然不是以像素為單位進行運動的,為了精確地表達物體的運動,需要選擇合適的精度來定義運動矢量。各視頻編解碼標準都定義了運動矢量的精度,運動矢量精度越高,越能精確地表達運動,但是代價就是傳輸運動矢量需要花費更多的bit。

          H.261中運動矢量是以整像素為精度的,H.264中運動矢量是以四分之一像素為精度的,AV1中還增加了八分之一精度。一般情況,時間上越近的幀,它們之間的相似性越高,也有例外,例如往復運動的場景等,可能相隔幾幀,甚至更遠的幀,會有更高的相似度。

          為了充分利用已經編碼過的幀來提高運動補償的準確度,從H.264開始引入了多參考幀技術。

          即:一個塊可以從已經編碼過的很多個參考幀中進行運動匹配,將匹配的幀索引和運動矢量信息都進行傳輸。

          那么如何得到一個塊的運動信息呢?最樸素的想法就是,將一個塊,在其參考幀中,逐個位置進行匹配檢查,匹配度最高的,就是最終的運動矢量。

          匹配度:常用的有SAD(Sum of Absolute Difference)、SSD(Sum of Squared Difference)等。逐個位置進行匹配度檢查,即常說的全搜索運動估計,其計算復雜度可想而知是非常高的。為了加快運動估計,我們可以減少搜索的位置數,類似的有很多算法,常用的如鉆石搜索、六邊形搜索、非對稱十字型多層次六邊形格點搜索算法等。

          以鉆石搜索為例,如下圖所示,以起始的藍色點為中心的9個匹配位置,分別計算這9個位置的SAD,如果SAD最小的是中心位置,下一步搜索中心點更近的周圍4個綠色點的SAD,選擇其中SAD最小的位置,繼續縮小范圍進行搜索;如果第一步中SAD最小的點不在中心,那么以該位置為中心,增加褐色的5或者3個點,繼續計算SAD,如此迭代,直到找到最佳匹配位置。

          編碼器在實現時,可根據實際的應用場景,對搜索算法進行選擇。

          例如:在實時音視頻場景下,計算復雜度是相對有限的,運動估計模塊要選擇計算量較小的算法,以平衡復雜度和編碼效率。當然,運動估計與運動補償的復雜度還與塊的大小,參考幀的個數,亞像素的計算等有關,在此不再深入展開。

          更多預測技術方面的原理這里就不再贅述。如果你對上面所述的預測技術理解上感到力不從心,這里有篇入門級的文章,可以先讀讀這篇《即時通訊音視頻開發(四):視頻編解碼之預測技術介紹》。

          8、寫在最后

          音視頻編解碼技術,歸根結底就是在有限的資源下(網絡帶寬、計算資源等),讓音質更清晰、視頻更高質。

          這其中,對于視頻來說,質量的提升仍然有很多可以深入研究的熱點問題。

          比如:基于人眼的主觀質量優化,主要利用人眼的視覺特性,將掩蔽效應、對比度靈敏度、注意力模型等與編碼相結合,合理分配碼率、減少編碼損失引起的視覺不適。

          AI在視頻編解碼領域的應用:包括將多種人工智能算法,如分類器、支持向量機、CNN等對編碼參數進行快速選擇,也可以使用深度學習對視頻進行編碼環外與編碼環內的處理,如視頻超分辨率、去噪、去霧、自適應動態范圍調整等編碼環外處理,達到提升視頻質量的目的。

          此外還有打破傳統混合編碼框架的深度神經網絡編碼,如Nvidia的Maxine視頻會議服務,利用深度學習來提取特征,然后對特征進行傳輸以節省帶寬。

          附錄:更多精華文章

          [1] 實時音視頻開發的其它精華資料:

          [2] 開源實時音視頻技術WebRTC的文章:

          本文已同步發布于“即時通訊技術圈”公眾號。

          ▲ 本文在公眾號上的鏈接是:點此進入。同步發布鏈接是:http://www.52im.net/thread-3581-1-1.html

          posted @ 2021-06-15 11:25 Jack Jiang 閱讀(149) | 評論 (0)編輯 收藏

          本文作者“商文默”,有修訂和改動。

          1、寫在前面

          即時通訊網整理的大量IM技術文章中(見本文末“參考資料”一節),有關消息可靠性和一致性問題的文章占了很大比重,原因是IM這類系統拋開各種眼花繚亂的產品功能和技術特性,保證消息的可靠性和一致性幾乎是IM產品必需的素質。

          試想如果一個IM連發出的消息都不知道對方到底能不能收到、發出的聊天內容對方看到的到底是不是“胡言亂語”(嚴重亂序問題),這樣的APP用戶肯定不會讓他在手機上過夜(肯定第一時間卸載了),因為最基本的聊天邏輯都無法實現,它已經失去了IM軟件本身的意義。

          不過,另一個方面來講,IM系統是不標準的(雖然曾經XMPP這種協議試圖解決這個問題,但事實證明那根本不現實),各家幾乎都是自已的私有協議、不同的實現邏輯,這也決定了即使同一個技術問題,對于IM來說很難有固定的實現套路和標準的解決方案。

          所以,對于本文來說,文中作者雖然提供了有關IM消息“可靠性”與“一致性”問題的解決方案,但方案到底合不合理、適不適合你,這就是仁者見仁、智者見智的事了。用人話說就是:本文內容僅供參考,具體的解決方案請務結合自已的系統構架和實現情況,多閱讀幾篇即時通訊網上有關這個技術話題的文章,取其精華,找到適合自已的技術方案和思路才是最明智的。

          學習交流:

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

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

          - 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK

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

          2、本文引言

          叢所周之,即時通訊聊天(IM)系統必需要解決消息可靠性及消息一致性問題(PS:如果具體IM系統是什么你都還沒弄明白,先讀這篇《零基礎IM開發入門(一):什么是IM系統?)。

          這兩個問題,通俗來說就是:

          • 1)消息可靠性:簡單來說就是不丟消息,會話一方發送消息,消息成功到達對方并正確顯示;
          • 2)消息一致性:包括發送一方消息一致及會話雙方消息一致,要求消息不重復,不亂序。

          本文會從典型的IM消息發送邏輯開始,簡單易懂地闡明消息可靠性、一致性問題的原理及可參考的技術解決方法,或許技術方案并不完美,但希望能為你的IM技術問題解決帶來啟發。

          3、典型IM消息發送過程

          IM的消息發送一般的實現過程可以分為兩個階段:

          • 1)發送方發送消息、服務端接收、返回消息 ACK 給發送方;
          • 2)服務端將消息推送到接收方。

          判斷消息發送是否成功主要依據第一階段——即服務器是否接受到消息。

          對于消息發送者來說,消息狀態可以分為三類:

          • 1)正在發送;
          • 2)發送成功;
          • 3)發送失敗。

          具體來說,這三類狀態的具體意義是:

          • 1)正在發送:發送方觸發發送事件開始,到收到服務端返回消息對應 ACK 之前;
          • 2)發送成功:發送方收到消息對應 ACK 回復;
          • 3)發送失敗:超過一定重發次數,未收到消息對應 ACK 回復。

          對應的消息發送流程如下圖所示:

          4、IM消息可靠性

          限于篇幅,對于IM消息可靠性的基本概念和詳細原理建議閱讀《零基礎IM開發入門(三):什么是IM系統的可靠性?》,本文著重談談解決思路。

          4.1 重發機制

          保證消息發送第一階段(見本文“3、典型IM消息發送過程”一節)消息成功發送的方法是設立重發機制:

          • 1)依據一定時長內是否收到消息對應 ACK,判斷消息是否要重發;
          • 2)如果超過預設時長,就重新發送;
          • 3)當重發次數超過預設次數,就不再重發,判定該消息發送失敗,修改消息發送狀態。

          PS:具體的完整方案級代碼實現,可以參考MobileIMSDK  中有關QoS機制的代碼實現。

          4.2 會話記錄檢查

          消息發送第二階段(見本文“3、典型IM消息發送過程”一節)服務端推送消息到接收方,如果連接斷開,會丟失消息。

          所以要保證消息完整,就需要在建立連接后,根據上一條消息(已經 ACK)時間戳,獲取會話記錄,一次返回一段時間內所有消息(PS:中大型應用中,消息的拉取也不是個簡單事情,詳情可以閱讀《IM開發干貨分享:如何優雅的實現大量離線消息的可靠投遞)。

          另一種保證方法是加入定時輪詢,檢查消息完整性,具體的思路如下圖所示。

          建立連接流程圖:

          4.3 需要考慮的兩個問題

          消息重發、會話記錄檢查需要考慮兩個問題:

          • 1)消息是否會重復發送;
          • 2)消息順序是否會被打亂。

          舉兩個例子。

          關于消息重發問題:

          • 1)如果丟消息的點在消息達到服務端之前,服務端并沒有收到消息,發送方重新發送丟失消息,服務端接收成功,不會產生兩條相同消息;
          • 2)而如果服務端接收到消息,返回 ACK 丟失,這時再發送一次相同消息,就可能造成消息重復。

          關于消息順序問題:

          • 1)如果發送方連發三條消息,第一、第三條成功被服務端接收,第二條丟了,那第三條消息是否會被記錄?
          • 2)如果這時第二條消息達到服務端,其順序是在第三條時間之前還是之后(服務端一般都會給記錄打一個時間戳)?

          5、IM消息一致性

          同上節一樣,對于IM消息一致性的基本概念和詳細原理建議閱讀《零基礎IM開發入門(四):什么是IM系統的消息時序一致性?》。

          5.1 使用 uuid 消息去重

          對于消息重發問題,可以給每條消息增加屬性 uuid 作為消息唯一標識,重發消息 uuid 不變,前端根據 uuid 去重。大致思路就是這樣。

          PS:對于IM來說,消息ID也是個很大的技術話題,有興趣可以讀下面這個系列:

          IM消息ID技術專題(一):微信的海量IM聊天消息序列號生成實踐(算法原理篇)

          IM消息ID技術專題(二):微信的海量IM聊天消息序列號生成實踐(容災方案篇)

          IM消息ID技術專題(三):解密融云IM產品的聊天消息ID生成策略

          IM消息ID技術專題(四):深度解密美團的分布式ID生成算法

          IM消息ID技術專題(五):開源分布式ID生成器UidGenerator的技術實現

          IM消息ID技術專題(六):深度解密滴滴的高性能ID生成器(Tinyid)

          5.2 使用向量時鐘進行消息排序

          對于消息排序問題:因為在聊天中,消息的順序對于發送方的表述有重要的影響,消息不完整或順序顛倒都可能造成語意不連貫,甚至曲解。所以需要保證發送方發送消息順序,而會話雙方消息排序需要考慮實際情況。

          在一般的認知里:狀態是正在發送的消息,應該還沒有被對方看到,只有發送成功的消息,才會被對方看到。但在實現中,消息發送成功是以服務器接收消息并返回 ACK 成功為判斷依據,而不是被對方接收到。

          那么就會出現這樣一個問題:如果一條消息狀態是正在發送,此時收到一條消息,那么收到的消息是在正在發送的消息之前還是之后?

          這是一個上下文關系,關鍵問題是:發送方是以哪條所見消息為依據發送消息的。

          這里提供一種思路:借鑒分布式系統中的向量時鐘算法(見《分布式系統中的向量時鐘算法)。

          先簡單描述向量時鐘算法:

          向量時鐘算法用于在分布式系統中生成事件偏序關系,并糾正因果關系。一個系統包含 N 個節點,每個節點產生的消息體中包含該節點的邏輯時鐘,整體系統的向量時鐘由 N 維邏輯時鐘組成,并在每個節點產生的消息體中傳遞。

          簡單來說,向量時鐘算法的實現原理如下:

          • 1)初始狀態,向量值為 0;
          • 2)每次節點處理完節點事件,該節點時鐘+1;
          • 3)每次節點發送消息,將包含自身時鐘的系統向量時鐘一起發送;
          • 4)每次節點收到消息,更新向量時鐘,該節點時鐘+1,其他節點對比每個節點本地保留的向量時鐘值和消息體中向量時鐘值,取最大值;
          • 5)節點同時收到多條消息,判斷接收消息的向量時鐘之間是否存在偏序關系。

          針對上述的第5)點:

          • 1)如果存在偏序關系,則合并向量時鐘,取偏序較大的向量時鐘;
          • 2)如果不存在偏序關系,則不能合并。

          偏序關系:如果 A 向量中的每一維都大于等于 B 向量,則 A、B 之間存在偏序關系,否則不存在偏序關系。

          對于IM為聊天消息排序來說,其實就是處理聊天消息的上下文語境,決定消息之間的因果關系。

          參考向量時鐘算法:假設有 N 個消息會話方,系統的向量時鐘由 N 維時鐘組成,向量時鐘在各方發送的消息體中傳遞,并依據向量時鐘排序。

          具體實現思路如下:

          • 1)系統向量時鐘設為 (0, 0, …, N);
          • 2)節點發送消息,更新系統向量時鐘,該節點時鐘加一,其他節點不變;
          • 3)節點接收消息,更新系統向量時鐘,該節點時鐘加一;其他節點對比每個節點本地保留的向量時鐘的值和消息中向量時鐘的值,取最大值;
          • 4)依據消息體內系統向量時鐘的偏序關系決定消息順序。

          針對上述第4)點:

          • 1)如果可以確定偏序關系,則根據偏序關系由小到大顯示;
          • 2)如果多條消息不能確定偏序關系,則按照自然順序(接收到的順序)顯示。

          向量時鐘在理論上可以解決大部分消息一致性的問題,但在實現中還需要考慮實際使用時的體驗。

          這其中最需要關注的問題是:是否要強制排序,或者說,如果實際顯示順序和向量時鐘之間的偏序關系不一致,是否要移動消息之間的順序。

          舉個例子:在一個有多人的會話中,如果有一方網速特別慢,收不到消息,也發不出消息。在他看到的最后的消息之后,其他人已經開始新的話題,這時他關于上一個話題的消息終于發送成功,并被其他人收到。

          此時就存在這樣一個問題:這條關于上一個話題的消息是顯示在最后,還是移到較早時間?

          • 1)如果顯示在最后,但消息內容和目前的話題不相關,其他人可能會感到莫名其妙;
          • 2)如果把消息移到較早時間,那么這條消息可能不會被其他人看到,或者看到前面多了一條消息,會有種突兀的感覺。

          IM 的場景很多,也很復雜,更多的時候需要從產品角度考慮問題。

          對于消息是否需要排序的問題,這里只提出一個比較通用的方案:建議會話中不強制排序,會話歷史記錄中按照向量時鐘的偏序關系進行排序。

          6、本文小結

          對于 IM 系統消息可靠性及一致性問題,通過消息重發機制保證消息成功被服務端接收,通過會話記錄檢查保證收取消息完整,從而保證整個消息發送過程的可靠性。使用 uuid 消息去重,參考向量時鐘算法進行消息排序,為保證消息一致性提供一種解決方案。

          總之,IM這類系統看似簡單,實則水深似海,如果你是IM開發新手,可以從《新手入門一篇就夠:從零開發移動端IM》這篇入手系統學習。如果你自認為已是IM老手,這里整理的 IM中大型架構設計 方面的文章或許可以參考一下。

          7、參考資料

          [1] 零基礎IM開發入門(三):什么是IM系統的可靠性?

          [2] 零基礎IM開發入門(四):什么是IM系統的消息時序一致性?

          [3] IM消息送達保證機制實現(一):保證在線實時消息的可靠投遞

          [4] IM消息送達保證機制實現(二):保證離線消息的可靠投遞

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

          [6] 一個低成本確保IM消息時序的方法探討

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

          [8] 完全自已開發的IM該如何設計“失敗重試”機制?

          [9] IM開發干貨分享:如何優雅的實現大量離線消息的可靠投遞

          [10] 從客戶端的角度來談談移動端IM的消息可靠性和送達機制

          [11] 一套億級用戶的IM架構技術干貨(下篇):可靠性、有序性、弱網優化等

          [12] 從新手到專家:如何設計一套億級消息量的分布式IM系統

          本文已同步發布于“即時通訊技術圈”公眾號。

          ▲ 本文在公眾號上的鏈接是:點此進入。同步發布鏈接是:http://www.52im.net/thread-3574-1-1.html

          posted @ 2021-06-07 20:34 Jack Jiang 閱讀(182) | 評論 (0)編輯 收藏

               摘要: 本文由喜馬拉雅技術團隊原創分享,原題《喜馬拉雅自研網關架構實踐》,有改動。1、引言網關是一個比較成熟的產品,基本上各大互聯網公司都會有網關這個中間件,來解決一些公有業務的上浮,而且能快速的更新迭代。如果沒有網關,要更新一個公有特性,就要推動所有業務方都更新和發布,那是效率極低的事,有網關后,這一切都變得不是問題。喜馬拉雅也是一樣,用戶數增長達到 6 億多的級別,Web 服務個數達到500+,目前我...  閱讀全文

          posted @ 2021-05-31 10:30 Jack Jiang 閱讀(247) | 評論 (0)編輯 收藏

               摘要: 本文來自“糊糊糊糊糊了”的分享,原題《實時消息推送整理》,有優化和改動。1、寫在前面對Web端即時通訊技術熟悉的開發者來說,我們回顧網頁端IM的底層通信技術,從短輪詢、長輪詢,到后來的SSE以及WebSocket,使用門檻越來越低(早期的長輪詢Comet這類技術實際屬于hack手段,使用門檻并不低),技術手段越來越先進,網頁端即時通訊技術的體驗也因此越來越好。但上周在編輯《...  閱讀全文

          posted @ 2021-05-25 12:18 Jack Jiang 閱讀(184) | 評論 (0)編輯 收藏

          本文由愛奇藝技術團隊原創分享,原題《構建通用WebSocket推送網關的設計與實踐》,有優化和改動。

          1、引言

          叢所周之,HTTP協議是一種無狀態、基于TCP的請求/響應模式的協議,即請求只能由客戶端發起、由服務端進行響應。在大多數場景,這種請求/響應的Pull模式可以滿足需求。但在某些情形:例如消息推送(IM中最為常見,比如IM的離線消息推送)、實時通知等應用場景,需要實時將數據同步到客戶端,這就要求服務端支持主動Push數據的能力。

          傳統的Web服務端推送技術歷史悠久,經歷了短輪詢、長輪詢等階段的發展(見《新手入門貼:史上最全Web端即時通訊技術原理詳解),一定程度上能夠解決問題,但也存在著不足,例如時效性、資源浪費等。HTML5標準帶來的WebSocket規范基本結束了這一局面,成為目前服務端消息推送技術的主流方案。

          在系統中集成WebSocket十分簡單,相關討論與資料很豐富。但如何實現一個通用的WebSocket推送網關尚未有成熟的方案。目前的云服務廠商主要關注iOS和安卓等移動端推送,也缺少對WebSocket的支持。本文分享了愛奇藝基于Netty實現WebSocket長連接實時推送網關時的實踐經驗總結。

          學習交流:

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

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

          - 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK

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

          2、專題目錄

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

          長連接網關技術專題(一):京東京麥的生產級TCP網關技術實踐總結

          長連接網關技術專題(二):知乎千萬級并發的高性能長連接網關技術實踐

          長連接網關技術專題(三):手淘億級移動端接入層網關的技術演進之路

          長連接網關技術專題(四):愛奇藝WebSocket實時推送網關技術實踐》(* 本文

          其它相關技術文章:

          絕對干貨:基于Netty實現海量接入的推送服務技術要點

          京東到家基于Netty的WebSocket應用實踐分享

          愛奇藝技術團隊分享的其它文章:

          愛奇藝技術分享:輕松詼諧,講解視頻編解碼技術的過去、現在和將來

          愛奇藝技術分享:愛奇藝Android客戶端啟動速度優化實踐總結

          愛奇藝移動端網絡優化實踐分享:網絡請求成功率優化篇

          3、舊方案存在的技術痛點

          愛奇藝號是我們內容生態的重要組成,作為前臺系統,對用戶體驗有較高要求,直接影響著創作者的創作熱情。

          目前,愛奇藝號多個業務場景中用到了WebSocket實時推送技術,包括:

          • 1)用戶評論:實時的將評論消息推送到瀏覽器;
          • 2)實名認證:合同簽署前需要對用戶進行實名認證,用戶掃描二維碼后進入第三方的認證頁面,認證完成后異步通知瀏覽器認證的狀態;
          • 3)活體識別:類似實名認證,當活體識別完成后,異步將結果通知瀏覽器。

          在實際的業務開發中,我們發現,WebSocket實時推送技術在使用中存在一些問題。

          這些問題是:

          • 1)首先:WebSocket技術棧不統一,既有基于Netty實現的,也有基于Web容器實現的,給開發和維護帶來困難;
          • 2)其次:WebSocket實現分散在在各個工程中,與業務系統強耦合,如果有其他業務需要集成WebSocket,面臨著重復開發的窘境,浪費成本、效率低下;
          • 3)第三:WebSocket是有狀態協議的,客戶端連接服務器時只和集群中一個節點連接,數據傳輸過程中也只與這一節點通信。WebSocket集群需要解決會話共享的問題。如果只采用單節點部署,雖然可以避免這一問題,但無法水平擴展支撐更高負載,有單點的風險;
          • 4)最后:缺乏監控與報警,雖然可以通過Linux的Socket連接數大致評估WebSocket長連接數,但數字并不準確,也無法得知用戶數等具有業務含義的指標數據;無法與現有的微服務監控整合,實現統一監控和報警。

          PS:限于篇幅本文不詳細介紹WebSocket技術本身,有興趣可以詳讀《WebSocket從入門到精通,半小時就夠!》。

          4、新方案的技術目標

          如上節所示,為了解決舊方案中存在的問題,我們需要實現統一的WebSocket長連接實時推送網關。

          這套新的網關需要具備如下特點:

          • 1)集中實現長連接管理和推送能力:統一技術棧,將長連接作為基礎能力沉淀,便于功能迭代和升級維護;
          • 2)與業務解耦:將業務邏輯與長連接通信分離,使業務系統不再關心通信細節,也避免了重復開發,浪費研發成本;
          • 3)使用簡單:提供HTTP推送通道,方便各種開發語言的接入。業務系統只需要簡單的調用,就可以實現數據推送,提升研發效率;
          • 4)分布式架構:實現多節點的集群,支持水平擴展應對業務增長帶來的挑戰;節點宕機不影響服務整體可用性,保證高可靠;
          • 5)多端消息同步:允許用戶使用多個瀏覽器或標簽頁同時登陸在線,保證消息同步發送;
          • 6)多維度監控與報警:自定義監控指標與現有微服務監控系統打通,出現問題時可及時報警,保證服務的穩定性。

          5、新方案的技術選型

          在眾多的WebSocket實現中,從性能、擴展性、社區支持等方面考慮,最終選擇了Netty。Netty是一個高性能、事件驅動、異步非阻塞的網絡通信框架,在許多知名的開源軟件中被廣泛使用。

          PS:如果你對Netty知之甚少,可以詳讀以下兩篇:

          WebSocket是有狀態的,無法像直接HTTP以集群方式實現負載均衡,長連接建立后即與服務端某個節點保持著會話,因此集群下想要得知會話屬于哪個節點有點困難。

          解決以上問題一般有兩種技術方案:

          • 1)一種是使用類似微服務的注冊中心來維護全局的會話映射關系;
          • 2)一種是使用事件廣播由各節點自行判斷是否持有會話,兩種方案對比如下表所示。

          WebSocket集群方案:

          綜合考慮實現成本與集群規模,選擇了輕量級的事件廣播方案。

          實現廣播可以選擇基于RocketMQ的消息廣播、基于Redis的Publish/Subscribe、基于ZooKeeper的通知等方案,其優缺點對比如下表所示。從吞吐量、實時性、持久化、實現難易等方面考慮,最終選擇了RocketMQ。

          廣播的實現方案對比:

          6、新方案的實現思路

          6.1 系統架構

          網關的整體架構如下圖所示:

          網關的整體流程如下:

          1)客戶端與網關任一節點握手建立起長連接,節點將其加入到內存維護的長連接隊列。客戶端定時向服務端發送心跳消息,如果超過設定的時間仍沒有收到心跳,則認為客戶端與服務端的長連接已斷開,服務端會關閉連接,清理內存中的會話。

          2)當業務系統需要向客戶端推送數據時,通過網關提供的HTTP接口將數據發向網關。

          3)網關在接收到推送請求后,將消息寫入RocketMQ。

          4)網關作為消費者,以廣播模式消費消息,所有節點都會接收到消息。

          5)節點接收到消息后判斷推送的消息目標是否在自己內存中維護的長連接隊列里,如果存在則通過長連接推送數據,否則直接忽略。

          網關以多節點方式構成集群,每節點負責一部分長連接,可實現負載均衡,當面對海量連接時,也可以通過增加節點的方式分擔壓力,實現水平擴展。

          同時,當節點出現宕機時,客戶端會嘗試重新與其他節點握手建立長連接,保證服務整體的可用性。

          6.2 會話管理

          WebSocket長連接建立起來后,會話維護在各節點的內存中。SessionManager組件負責管理會話,內部使用了哈希表維護了UID與UserSession的關系。

          UserSession代表用戶維度的會話,一個用戶可能會同時建立多個長連接,因此UserSession內部同樣使用了一個哈希表維護Channel與ChannelSession的關系。

          為了避免用戶無限制的創建長連接,UserSession在內部的ChannelSession超過一定數量后,會將最早建立的ChannelSession關閉,減少服務器資源占用。SessionManager、UserSession、ChannelSession的關系如下圖所示。

          SessionManager組件:

          6.3 監控與報警

          為了了解集群建立了多少長連接、包含了多少用戶,網關提供了基本的監控與報警能力。

          網關接入了Micrometer,將連接數與用戶數作為自定義指標暴露,供Prometheus進行采集,實現了與現有的微服務監控系統打通。

          Grafana中方便地查看連接數、用戶數、JVM、CPU、內存等指標數據,了解網關當前的服務能力與壓力。報警規則也可以在Grafana中配置,當數據異常時觸發奇信(內部報警平臺)報警。

          7、新方案的性能壓測

          壓測準備:

          • 1)壓測選擇兩臺配置為4核16G的虛擬機,分別作為服務器和客戶端;
          • 2)壓測時選擇為網關開放了20個端口,同時建立20個客戶端;
          • 3)每個客戶端使用一個服務端端口建立起5萬連接,可以同時創建百萬個連接。

          連接數(百萬級)與內存使用情況如下圖所示:

          給百萬個長連接同時發送一條消息,采用單線程發送,服務器發送完成的平均耗時在10s左右,如下圖所示。

          服務器推送耗時: 

          一般同一用戶同時建立的長連接都在個位數。以10個長連接為例,在并發數600、持續時間120s條件下壓測,推送接口的TPS大約在1600+,如下圖所示。

          長連接10、并發600、持續時間120s的壓測數據:

          當前的性能指標已滿足我們的實際業務場景,可支持未來的業務增長。

          8、新方案的實際應用案例

          為了更生動的說明優化效果,文章最后,我們也以封面圖添加濾鏡效果為例,介紹一個愛奇藝號使用新WebSocket網關方案的案例。

          愛奇藝號自媒體發表視頻時,可選擇為封面圖添加濾鏡效果,引導用戶提供提供更優質的封面。

          當用戶選擇一個封面圖后,會提交異步的后臺處理任務。當異步任務處理完成后,通過WebSocket將不同濾鏡效果處理后的圖片返回給瀏覽器,業務場景如下圖所示。

          從研發效率方面考慮,如果在業務系統中集成WebSocket,至少需要1-2天的開發時間。

          如果直接使用新的WebSocket網關的推送能力,只需要簡單的接口調用就實現了數據推送,開發時間降低到分鐘級別,研發效率大大提高。

          從運維成本方面考慮,業務系統不再含有與業務邏輯無關的通信細節,代碼的可維護性更強,系統架構變得更加簡單,運維成本大大降低。

          9、寫在最后

          WebSocket是目前實現服務端推送的主流技術,恰當使用能夠有效提供系統響應能力,提升用戶體驗。通過WebSocket長連接網關可以快速為系統增加數據推送能力,有效減少運維成本,提高開發效率。

          長連接網關的價值在于:

          • 1)它封裝了WebSocket通信細節,與業務系統解耦,使得長連接網關與業務系統可獨立優化迭代,避免重復開發,便于開發與維護;
          • 2)網關提供了簡單易用的HTTP推送通道,支持多種開發語言接入,便于系統集成和使用;
          • 3)網關采用了分布式架構,可以實現服務的水平擴容、負載均衡與高可用;
          • 4)網關集成了監控與報警,當系統異常時能及時預警,保證服務的健康和穩定。

          目前,新的WebSocket長連接實時網關已在愛奇藝號圖片濾鏡結果通知、MCN電子簽章等多個業務場景中得到應用。

          未來還有許多方面需要探索,例如消息的重發與ACK、WebSocket二進制數據的支持、多租戶的支持等。

          附錄:更多相關技術資料

          [1] 有關WEB端即時通訊開發:

          新手入門貼:史上最全Web端即時通訊技術原理詳解

          Web端即時通訊技術盤點:短輪詢、Comet、Websocket、SSE

          SSE技術詳解:一種全新的HTML5服務器推送事件技術

          Comet技術詳解:基于HTTP長連接的Web端實時通信技術

          新手快速入門:WebSocket簡明教程

          WebSocket詳解(一):初步認識WebSocket技術

          WebSocket詳解(二):技術原理、代碼演示和應用案例

          WebSocket詳解(三):深入WebSocket通信協議細節

          WebSocket詳解(四):刨根問底HTTP與WebSocket的關系(上篇)

          WebSocket詳解(五):刨根問底HTTP與WebSocket的關系(下篇)

          WebSocket詳解(六):刨根問底WebSocket與Socket的關系

          socket.io實現消息推送的一點實踐及思路

          LinkedIn的Web端即時通訊實踐:實現單機幾十萬條長連接

          Web端即時通訊技術的發展與WebSocket、Socket.io的技術實踐

          Web端即時通訊安全:跨站點WebSocket劫持漏洞詳解(含示例代碼)

          開源框架Pomelo實踐:搭建Web端高性能分布式IM聊天服務器

          使用WebSocket和SSE技術實現Web端消息推送

          詳解Web端通信方式的演進:從Ajax、JSONP 到 SSE、Websocket

          MobileIMSDK-Web的網絡層框架為何使用的是Socket.io而不是Netty?

          理論聯系實際:從零理解WebSocket的通信原理、協議格式、安全性

          微信小程序中如何使用WebSocket實現長連接(含完整源碼)

          八問WebSocket協議:為你快速解答WebSocket熱門疑問

          Web端即時通訊實踐干貨:如何讓你的WebSocket斷網重連更快速?

          WebSocket從入門到精通,半小時就夠!

          WebSocket硬核入門:200行代碼,教你徒手擼一個WebSocket服務器

          >> 更多同類文章 ……

          [2] 有關推送技術的文章:

          一個基于MQTT通信協議的完整Android推送Demo

          求教android消息推送:GCM、XMPP、MQTT三種方案的優劣

          移動端實時消息推送技術淺析

          絕對干貨:基于Netty實現海量接入的推送服務技術要點

          極光推送系統大規模高并發架構的技術實踐分享

          魅族2500萬長連接的實時消息推送架構的技術實踐分享

          專訪魅族架構師:海量長連接的實時消息推送系統的心得體會

          基于WebSocket實現Hybrid移動應用的消息推送實踐(含代碼示例)

          一個基于長連接的安全可擴展的訂閱/推送服務實現思路

          實踐分享:如何構建一套高可用的移動端消息推送系統?

          Go語言構建千萬級在線的高并發消息推送系統實踐(來自360公司)

          騰訊信鴿技術分享:百億級實時消息推送的實戰經驗

          百萬在線的美拍直播彈幕系統的實時推送技術實踐之路

          京東京麥商家開放平臺的消息推送架構演進之路

          技術干貨:從零開始,教你設計一個百萬級的消息推送系統

          長連接網關技術專題(四):愛奇藝WebSocket實時推送網關技術實踐

          >> 更多同類文章 ……

          本文已同步發布于“即時通訊技術圈”公眾號。

          ▲ 本文在公眾號上的鏈接是:點此進入。同步發布鏈接是:http://www.52im.net/thread-3539-1-1.html

          posted @ 2021-05-17 23:12 Jack Jiang 閱讀(308) | 評論 (0)編輯 收藏

               摘要: 本文引用了作者“大古同學”的“二維碼掃碼登錄是什么原理”一文的主要內容,為了更好的理解和閱讀,即時通訊網收錄時有修訂和改動,感謝原作者的分享。1、引言自從微信的PC端使用掃碼登陸認證邏輯后,這種方式似乎在越來越多的IM中看到(雖然我個人認為這種登錄方式很酷,但并不方便,尤其手機不大身邊的時候)。 ▲ 上圖微信PC端的掃碼登錄界面...  閱讀全文

          posted @ 2021-05-10 13:42 Jack Jiang 閱讀(194) | 評論 (0)編輯 收藏

               摘要: 本文原題“百度直播消息服務架構實踐”,由百度APP消息中臺團隊原創分享于“百度Geek說”公眾號,為了讓文章內容更通俗易懂,本次已做排版優化和內容重新劃分,原文鏈接在文末。1、引言一套完整的直播系統核心功能有兩個:1)實時音視頻的推拉流;2)直播間消息流的收發(包括聊天消息、彈幕、指令等)。本文主要分享的是百度直播的消息系統的架構設計實踐和演進過程。...  閱讀全文

          posted @ 2021-04-27 15:17 Jack Jiang 閱讀(213) | 評論 (0)編輯 收藏

               摘要: 文中引用了參考資料中的部分內容,本文參考資料詳見文末“參考資料”一節,感謝資料分享者。1、引言對于IM開發者而言,網絡保活這件事再熟悉不過了,比如這是我最近一篇有關網絡保活話題文章《一文讀懂即時通訊應用中的網絡心跳包機制:作用、原理、實現思路等》,以及我分享的大量代碼實戰編碼中也都必須要考慮這個問題的實現,比如最近的這篇《跟著源碼學IM(五):正確理解IM長連接、心跳及重連...  閱讀全文

          posted @ 2021-04-19 15:10 Jack Jiang 閱讀(293) | 評論 (0)編輯 收藏

               摘要: 本文作者芋艿,原題“使用 Netty 實現 IM 聊天賊簡單”,本底價有修訂和改動。一、本文引言上篇《跟著源碼學IM(七):手把手教你用WebSocket打造Web端IM聊天》中,我們使用 WebSocket 實現了一個簡單的 IM 功能,支持身份認證、私聊消息、群聊消息。然后就有人發私信,希望使用純 Netty 實現一個類似的功能,因此就有了本文。注:源碼請從同步鏈接附件...  閱讀全文

          posted @ 2021-04-12 15:43 Jack Jiang 閱讀(326) | 評論 (0)編輯 收藏

          僅列出標題
          共51頁: First 上一頁 24 25 26 27 28 29 30 31 32 下一頁 Last 
          Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 宣化县| 且末县| 临颍县| 邯郸县| 南陵县| 苍溪县| 巴林右旗| 隆回县| 河曲县| 梅河口市| 瑞丽市| 吉木萨尔县| 泸西县| 湟源县| 乌拉特前旗| 东乡族自治县| 曲阜市| 岑溪市| 鄂托克前旗| 汉寿县| 桦川县| 静乐县| 本溪| 怀化市| 涟水县| 巴林左旗| 子长县| 德化县| 垦利县| 兴化市| 岗巴县| 绥棱县| 中方县| 肃宁县| 洪湖市| 青龙| 壶关县| 台前县| 白玉县| 府谷县| 凉山|