溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

WebRTC 開發(fā)實(shí)踐:如何實(shí)現(xiàn) SFU 服務(wù)器

發(fā)布時間:2020-08-05 16:30:44 來源:網(wǎng)絡(luò) 閱讀:2992 作者:Jhuster 欄目:軟件技術(shù)

上一篇文章《WebRTC 開發(fā)實(shí)踐:為什么你需要 SFU 服務(wù)器》我們了解了 WebRTC SFU 服務(wù)器的基本原理和必要性,解決了 What 和 Why,本文則更近一步,探究一下實(shí)現(xiàn) SFU 服務(wù)器的關(guān)鍵技術(shù)點(diǎn)有哪些 ?重點(diǎn)解決一下 How

1 什么是 SFU ?

首先,我們再看一次 SFU 服務(wù)器的定義,什么是 SFU ?

SFU 的全稱是:Selective Forwarding Unit,是一種路由和轉(zhuǎn)發(fā) WebRTC 客戶端音視頻數(shù)據(jù)流的服務(wù)端程序。

WebRTC 開發(fā)實(shí)踐:如何實(shí)現(xiàn) SFU 服務(wù)器

如圖所示,SFU 服務(wù)器最核心的功能就是與每一個 WebRTC Peer 客戶端建立鏈接,分別接收來自他們的音視頻數(shù)據(jù),并實(shí)現(xiàn)?one-to-many 的能力(即把一個客戶端的流轉(zhuǎn)發(fā)到其他 WebRTC Peer 客戶端),那么,如果我們要實(shí)現(xiàn)這樣一臺 SFU 服務(wù)器,有哪些需要解決和處理的問題呢 ?

我們可以想象一下 Web 服務(wù)器和直播服務(wù)器的工作原理,瀏覽器/直播客戶端,要想完成與服務(wù)器之間的數(shù)據(jù)交換,通常離不開如下幾個步驟:

  1. 通過 DNS 解析,拿到服務(wù)器的 IP 地址;然后通過 “約定” 的端口(如:80 或者 1935)連接到服務(wù)器

  2. 客戶端使用 “約定” 的信令協(xié)議(如:HTTP,RTMP),發(fā)送請求給服務(wù)器,實(shí)現(xiàn)數(shù)據(jù)交換的準(zhǔn)備工作

  3. 客戶端開始上行數(shù)據(jù)給服務(wù)器,或者服務(wù)器開始下發(fā)數(shù)據(jù)到客戶端,結(jié)束后,通過信令關(guān)閉連接

  4. 靜態(tài)的資源型的數(shù)據(jù)(文件、網(wǎng)頁),通常服務(wù)端是讀取磁盤上的數(shù)據(jù)拷貝一份給需要的客戶端

  5. 非靜態(tài)的實(shí)時數(shù)據(jù)(如:直播流),服務(wù)器則通過在 “內(nèi)存” 中拷貝并轉(zhuǎn)發(fā)給需要的客戶端

同樣,WebRTC 客戶端與 SFU 服務(wù)器之間的交互,也是離不開這些步驟的,特別是 4/5,其實(shí)就是所謂的 one-to-many 能力。

2 ?信令和傳輸通道的建立

首先我們解決第一個問題,即 WebRTC 客戶端是如何跟 SFU 服務(wù)器建立數(shù)據(jù)傳輸通道的 ?

WebRTC 開發(fā)實(shí)踐:如何實(shí)現(xiàn) SFU 服務(wù)器

如圖,我們先看看瀏覽器與 Web 服務(wù)器的建聯(lián)過程:瀏覽器通過 DNS 解析 URL 中的域名,拿到 IP 后通過 80 端口連接上服務(wù)器(后續(xù)的數(shù)據(jù)傳輸均復(fù)用這條 TCP 鏈路)。

WebRTC 其實(shí)也是類似的,但是與標(biāo)準(zhǔn)的 HTTP 服務(wù)或者 RTMP 直播服務(wù)相比,還是有些區(qū)別的,如下:

  1. 信令和數(shù)據(jù)通道是 “分離” 的,信令目前沒有統(tǒng)一的實(shí)現(xiàn)方案,可以使用任何方案(如:HTTP、TCP 自定義協(xié)議、SIP 等等),但是數(shù)據(jù)并不走這條信令鏈路,而是走單獨(dú)的 UDP 端口

  2. 數(shù)據(jù)通道使用的 UDP 協(xié)議,不像 TCP?有 “連接” 的概念,客戶端僅僅知道服務(wù)器的 UDP 端口,但不 “連接” 是無法預(yù)判傳輸通道是否真的 OK(主要是部分 NAT 網(wǎng)關(guān)類型的限制,導(dǎo)致并不是所有 UDP 傳輸都能通),因此需要借助一些框架和協(xié)議來判斷 UDP 通道的可用性(即 ICE 協(xié)議)

上述內(nèi)容分析完了,我們就可以看看如何實(shí)現(xiàn) SFU 的信令和傳輸通道了:

  1. 實(shí)現(xiàn) HTTP Web Server 服務(wù)(或者 SIP 或者基于 TCP 自定義協(xié)議),用于提供 “信令” 的支持(如:推流命令、拉流命令等)

  2. 通過 libnice 庫或者自己 coding 的方式,實(shí)現(xiàn) ICE 協(xié)議,用于提供 UDP “數(shù)據(jù)通道” 的檢測和建聯(lián)

  3. 實(shí)現(xiàn) UDP 數(shù)據(jù)監(jiān)聽和發(fā)送,用于接收客戶端的數(shù)據(jù),轉(zhuǎn)發(fā)其他客戶端的數(shù)據(jù)

3 需要實(shí)現(xiàn)哪些 “信令” ?

對于 HTTP 協(xié)議,實(shí)現(xiàn)的 “信令” 包括:GET,POST,DELETE 等等,定義了瀏覽器期望進(jìn)行的行為。同理,對于 SFU,我們也要定義一系列必要的信令,以約定客戶端和服務(wù)器對應(yīng)的行為,那具體有哪些呢 ?

其實(shí) WebRTC 客戶端,與 SFU 服務(wù)器需要協(xié)商的事情,無外乎就是如下幾點(diǎn):

  1. ICE 建聯(lián):交換 ICE 信息(用戶名、密碼、IP 地址、UDP 端口等)

  2. 發(fā)布流/取消發(fā)布流:客戶端通知服務(wù)器準(zhǔn)備好接收數(shù)據(jù)

  3. 訂閱流/取消訂閱流:客戶端通知服務(wù)器準(zhǔn)備好轉(zhuǎn)發(fā)數(shù)據(jù)

因此,SFU 服務(wù)器通過任意一種方式(HTTP/TCP 等),提供 ICE Connection/Publish/Subscribe 信令即可,SFU 在信令背后需要實(shí)現(xiàn)的邏輯分別如下:

1. ICE Connection:添加一路 UDP 通道

2. Publish:添加一個邏輯上的數(shù)據(jù) Producer,通過 UDP 通道 recv 客戶端的數(shù)據(jù),通知邏輯上的 Consumers

3. Subscribe:添加一個邏輯上的數(shù)據(jù) Consumer,收到 Producer 通知后,通過 UDP 通道 send 給客戶端


4 如何實(shí)現(xiàn) one-to-many ?

這是 SFU 最核心的功能,其實(shí)也不是 WebRTC SFU 特有,如前面所述,凡是非靜態(tài)資源型的服務(wù)(數(shù)據(jù)實(shí)時產(chǎn)生實(shí)時消費(fèi))均需要在服務(wù)端實(shí)現(xiàn) one-to-many,比較典型的例子就是 RTMP 直播流服務(wù)器,需要將客戶端推流上來的數(shù)據(jù),實(shí)時轉(zhuǎn)發(fā)給多個拉流的客戶端。

實(shí)現(xiàn)?one-to-many ,最重要的一點(diǎn)是需要把數(shù)據(jù)的生產(chǎn)者(Publisher)和數(shù)據(jù)的消費(fèi)者(Subscriber)關(guān)聯(lián)起來,怎么關(guān)聯(lián)呢 ?

WebRTC 傳輸?shù)囊粢曨l數(shù)據(jù),實(shí)際上是封裝在 RTP 包里面,RTP 包頭有個很重要的字段,叫做 ×××C(同步源標(biāo)識),就是這路流的唯一標(biāo)識,如圖:

WebRTC 開發(fā)實(shí)踐:如何實(shí)現(xiàn) SFU 服務(wù)器

數(shù)據(jù)的生產(chǎn)者(Publisher)和數(shù)據(jù)的消費(fèi)者(Subscriber)即可通過 ×××C 來關(guān)聯(lián),實(shí)現(xiàn)?one-to-many 的核心代碼邏輯抽象如下:

WebRTC 開發(fā)實(shí)踐:如何實(shí)現(xiàn) SFU 服務(wù)器

即:當(dāng) SFU 接收到?Publisher 發(fā)送上來的數(shù)據(jù)后,輪詢一下所有的?Subscribers,如果 ×××C 匹配成功,則將數(shù)據(jù)轉(zhuǎn)發(fā)給這個客戶端。

5 數(shù)據(jù)傳輸協(xié)議

WebRTC 采用的是標(biāo)準(zhǔn)的 RTP/RTCP 協(xié)議進(jìn)行數(shù)據(jù)的封包和網(wǎng)絡(luò)狀態(tài)反饋,因此,SFU 服務(wù)器也需要支持?RTP/RTCP 的封包和解包,從而能夠 “理解” 客戶端的 UDP 數(shù)據(jù)包的含義,如:提取出 ×××C 或者 timestamp 等必要的信息,也能及時地向客戶端反饋網(wǎng)絡(luò)狀態(tài)(RTCP)。

關(guān)于 RTP/RTCP 傳輸協(xié)議,已經(jīng)發(fā)展多年,是比較成熟的多媒體傳輸協(xié)議了,也有很多不錯的開源庫,這里就不再贅述了。

6 小結(jié)

以上就是關(guān)于如何實(shí)現(xiàn) SFU 服務(wù)器最核心的知識點(diǎn)了,暫且就分享到這里了,如有疑問的小伙伴歡迎來信 lujun.hust@gmail.com 交流。另外,也歡迎大家關(guān)注我的新浪微博 @盧_俊 或者 微信公眾號 @Jhuster 獲取最新的文章和資訊。

WebRTC 開發(fā)實(shí)踐:如何實(shí)現(xiàn) SFU 服務(wù)器


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI