點選圖片報名社交泛娛樂出海賦能會【廣州站】
在音視訊通話,尤其是多人群組通話場景,過大的請求包體會導致客戶端頻繁報錯、連線超時等問題。關注【融雲全球網際網路通訊雲】瞭解更多
為解決這一問題,融雲引入並最佳化相關演算法,使呼叫和全域性雙向請求傳輸體積下降了 85%,為使用者提供更流暢的使用體驗。
業界主流壓縮演算法
HTTP(Hypertext Transfer Protocol,超文字傳輸協議)是一種請求/響應式的應用層協議。客戶端與伺服器建立連線後,向伺服器傳送一個請求;伺服器接到請求後,給予相應的響應資訊。
HTTP 包體主流壓縮演算法有 MiniSDP、Brotli、Gzip 等。
MiniSDP
在進行音視訊通話時,首先需要交換信令,SDP 互換就是其中的重要資訊,讓雙方瞭解彼此的音影片引數及能力。所以,包體中絕大部分是 SDP 內容,即專門用於描述多媒體資料的會話描述協議。
其主要內容包括會話所有者有關的引數、會話的起始時間和結束時間、傳送方所支援的媒體型別、媒體的連線資訊等,參與者人數越多,SDP 內容佔比越高。
因此,將 SDP 改造為 MiniSDP 一定程度上可以對 HTTP 包體進行壓縮。
WebRTC 的 SDP 用文字字串表示比較冗長,不利於快速高效傳輸;MiniSDP 把 SDP 文字壓縮成高效傳輸的二進位制流,具有高壓縮率、強擴充套件性、使用便利性。
mini_sdp 由 mini_sdp header、n 個 session 級別擴充套件和 n 個 media 三部分組成,具體結構如下:
mini_sdp header 主要定義 mini_sdp 傳輸所需要的一些輔助資訊及 ice 候選地址資訊,各欄位的長度及含義如下:
struct MiniSdpHdr {
uint16_t version; //2B, 表示該mini_sdp的版本號
uint8_t is_bundle:1; //1b, 0-未繫結, 1-繫結
uint8_t plan_type:1; //1b, 0-plan-b, 1-unifield-plan
uint8_t dtls_role:2; //2b, 0-actpass, 1-active, 2-passive
uint8_t encrypt_switch:1; //1b, 0-不加密, 1-encrypt_key加密
uint8_t ip_type:1; //1b, 0-ipv4, 1-ipv6
uint8_t ice_type:1; //1b, 0-full-lite, 1-ice-lite
uint8_t reversed1:1; //1b, 保留位
uint8_t reversed2:5; //5b, 保留位
uint8_t candidate_num:3; //3b, ice 候選地址的個數
uint16_t media_num; //2B, 原sdp中m行的個數
} __attribute__((packed));
注意:
1、version和media_num以網路位元組序傳輸;
2、必須支援ice,並且rtp和rtcp共用埠,否則會在media中增加ip,rtpPort,rtcpPort的開銷;
3、media_num用uint16_t,防止大會議使用unifield plan
struct MiniCandidateDesc {
uint32_t ip[4]; //ipv4, ipv6轉換後的ip
uint32_t priority; //優先順序
uint16_t port; //埠
uint8_t type; //0-host, 1-srflx, 2-prflx, 3-relay
} __attribute__((packed));
注意:priority和port以網路位元組序傳輸
session extenses 主要描述會話資訊:
{
uint16_t ufrag_len; //長度傳輸時使用網路位元組序
const char* ice_ufrag;
uint16_t pwd_len;
const char* ice_pwd;
uint16_t key_len;
const char* encrypt_key;
uint16_t session_id_len;
const char* session_id;
uint16_t session_version_len;
const char* session_version;
}
session extenses 結構示意圖
struct MiniMediaHdr {
uint8_t media_type:2; //2b, 0-audio, 1-video, 2-data
uint8_t codec_num:6; //6b, 表示以下有多少個codec描述
uint8_t direction:2; //2b, 0-sendrecv, 1-recvonly, 2-sendonly, 3-inactive
uint8_t rtcp_mux:1; //1b, 0-不使能rtcp-mux, 1-使能rtcp-mux
uint8_t reversed:5; //5b, 保留
uint8_t rtp_extense_num;//1B, 表示以下有多少個rtp extense描述
uint16_t track_num; //2B, 表示以下有多少個track描述
} __attribute__((packed));
注意:track_num以網路位元組序傳輸
目前,客戶端和伺服器都不支援 MiniSDP,需要 SDP 與 MiniSDP 二者之間完成轉換。
經測試發現,原始 SDP 在 MiniSDP encode 和 decode 後,部分屬性會丟失或改變,還需對 MiniSDP 進行定製化開發支援。
資料主權
Brotli 是 Google 在 2015 年 9 月推出的一種壓縮演算法。它透過變種的 LZ77 演算法、Huffman 編碼及二階文字建模等方式進行資料壓縮,與其他壓縮演算法相比,Brotli 有著更高的壓縮效率。
根據 Google 釋出的研究報告,Brotli 壓縮演算法具有多個特點,最典型的是以下三個:
- 針對常見的 Web 資源內容,Brotli 的效能相比 Gzip 提高了 17%-25%;
- 當 Brotli 壓縮級別為 1 時,壓縮率比 Gzip 壓縮等級為 9(最高)時還要高;
- 在處理不同 HTML 文件時,Brotli 依然能夠提供非常高的壓縮率。
Brotli 在壓縮程度上有著絕對的優勢,但是這些優勢是用其他代價換來的。Brotli 壓縮操作所花費的時間會隨著壓縮級別的增加而增加。
簡而言之,就是 Brotli 需要更多的計算能力,而計算能力需求的增加代表著裝置和軟體設施的成本上漲。另外,Brotli 要求瀏覽器必須支援與 HTTPS 一起使用,這也是它相比在瀏覽器支援量上比 Gzip 少的原因。
畢竟,Gzip 是同時支援 HTTP 和 HTTPS 的。
Gzip
Gzip 是 GNUzip 的縮寫,基於 DEFLATE 演算法實現,是 LZ77 和霍夫曼編碼的組合。
作為一種比較常用的資料壓縮方式,它最早用於 UNIX 系統的檔案壓縮。
HTTP 協議上的 Gzip 編碼是一種用來改進 Web 應用程式效能的技術,Web 伺服器和客戶端(瀏覽器)必須共同支援 Gzip。
目前,主流的瀏覽器如 Chrome、Firefox、IE 等和常見的伺服器如 Apache、Nginx、IIS 都支援該協議。
Gzip 常用於網站內容壓縮傳輸,以減少網路消耗,壓縮比率在 3 到 10 倍左右,可以大大節省伺服器的網路頻寬。
在實際應用中,它並不是對所有檔案進行壓縮,通常只壓縮靜態檔案。
服務中使用 Gzip 的方案示意如下:
各方案 PK 結果
資料壓縮傳輸的效率主要透過壓縮率和解壓縮時間來綜合判斷,三種方案的原始資料壓縮後資料大小如下:
實際包體長度 19678 的 Gzip 和 Brotli 壓縮比率與解壓縮時間對比如下:
在資料壓縮率上 Brotli > Gzip > MiniSDP,在解壓縮效率上 MiniSDP > Gzip > Brotli。
Gzip 壓縮在壓縮率上與 Brotli 相差不多,在各種瀏覽器中相容性更強,且解壓縮效率優於 Brotli。
綜合考慮相容性、開發量等因素,融雲選擇 Gzip 方案對呼叫和全域性雙向請求進行最佳化,使傳輸體積下降 85%,大大減少了傳輸效率問題和連線超時問題。