SRS 5.0支持WebRTC over TCP

Written by Winlin, 李鵬

在很多網(wǎng)絡(luò)條件下,WebRTC不適合使用UDP傳輸,因此支持TCP傳輸是極其重要的能力;而且SRS支持的是直接TCP傳輸?shù)姆绞?,避免使用TURN中轉(zhuǎn)帶來(lái)的額外網(wǎng)絡(luò)層問(wèn)題;這對(duì)于LoadBalancer也是非常友好的,一般支持TCP會(huì)更友好。

Why Important?

大約兩年前SRS支持了WebRTC,雖然支持了不少功能但還不夠完善,這兩年收到了很多反饋,其中常見(jiàn)的而且非常重要的有:

  • 用不了UDP,可能是公司網(wǎng)絡(luò)封掉了UDP協(xié)議,或者封掉了小于10000的UDP端口,總之各種不可用的場(chǎng)景,SRS有個(gè)小工具檢測(cè)UDP端口可用性,請(qǐng)參考#2843
  • 媒體協(xié)議和端口太多了,TCP有RTMP(1935)和HTTP(80/443),UDP有WebRTC(8000)和SRT(10080),還有HTTP API端口(1985),如何讓協(xié)議端口更收斂?多開(kāi)一個(gè)端口就多一份麻煩。HTTP API和Stream使用同樣端口的問(wèn)題,請(qǐng)參考#2881。
  • UDP可用但丟包比較嚴(yán)重,有可能是系統(tǒng)設(shè)置問(wèn)題,也有可能是網(wǎng)絡(luò)設(shè)備或環(huán)境導(dǎo)致丟包,往往TCP是沒(méi)問(wèn)題的,請(qǐng)參考#2852

如果SRS能像HTTP-FLV那樣,在HTTP(80)端口傳輸媒體數(shù)據(jù),那該多么簡(jiǎn)單?多么可靠??!只要能上網(wǎng),HTTP(80)端口就一定是可用的。流傳輸圖如下:

Publisher --------RTC------> SRS --------RTC--------> Player
            (over TCP/80)           (over TCP/80)

Note: 實(shí)際上WebRTC是有個(gè)API請(qǐng)求的,所以這里還省略了HTTP API請(qǐng)求,可以在同樣端口上傳輸HTTP API,HTTP Stream和WebRTC數(shù)據(jù)。

專(zhuān)業(yè)人士一般會(huì)說(shuō):這個(gè)問(wèn)題可以用TURN解決,流傳輸圖如下:

Publisher -----> TURN ----> SRS -----> TURN -----> Player
         (over TURN/3478).      (over TURN/3478)

TURN的方案明顯是不好的,有幾個(gè)問(wèn)題:

  • 多引入了一個(gè)網(wǎng)元,需要額外考慮部署和依賴(lài)問(wèn)題,而且有些TURN可能還沒(méi)提供Docker。
  • 多引入了一個(gè)協(xié)議,看起來(lái)簡(jiǎn)單的協(xié)議(幾個(gè)交互),如何監(jiān)控和排查問(wèn)題,如何運(yùn)維都是非常麻煩的。
  • 延遲和成本問(wèn)題,多一跳就多一次延遲,多一份網(wǎng)元就多一個(gè)集群,這都是真金白銀的CPU消耗。

因此,WebRTC支持TCP傳輸,最好的方案是直接TCP傳輸而不是TURN協(xié)議,參考以下兩個(gè)RFC:

下面介紹下SRS目前的進(jìn)展。

What's Now?

SRS 5.0正式解決了這個(gè)問(wèn)題:

  • HTTP API、HTTP Stream、WebRTC over TCP,可以全部復(fù)用一個(gè)TCP端口,比如HTTPS(443)。
  • 支持直接UDP或TCP傳輸,不依賴(lài)TURN協(xié)議,沒(méi)有額外的網(wǎng)元,沒(méi)有額外部署和資源消耗。
  • 可部署在LoadBalancer后面(已實(shí)現(xiàn)),可配合Proxy(未實(shí)現(xiàn))或者Cluster(未實(shí)現(xiàn))實(shí)現(xiàn)負(fù)載均衡和擴(kuò)容。

Note: 注意需要升級(jí)到v5.0.60+,若使用Docker也請(qǐng)先確認(rèn)SRS的版本。

我們先看最簡(jiǎn)單情況,用一個(gè)TCP(8080)端口,支持RTC推拉流:

docker run --rm -it -p 8080:8080/tcp \
  -e CANDIDATE="192.168.3.82" \
  -e SRS_HTTP_API_LISTEN=8080 \
  -e SRS_RTC_SERVER_TCP_ENABLED=on \
  -e SRS_RTC_SERVER_TCP_LISTEN=8080 \
  -e SRS_RTC_SERVER_PROTOCOL=tcp \
  registry.cn-hangzhou.aliyuncs.com/ossrs/srs:v5.0.60

一般需要支持直播,所以下面,只用一個(gè)TCP(8080)端口,支持RTC和直播:

docker run --rm -it -p 8080:8080/tcp \
  -e CANDIDATE="192.168.3.82" \
  -e SRS_VHOST_RTC_RTC_TO_RTMP=on \
  -e SRS_HTTP_API_LISTEN=8080 \
  -e SRS_RTC_SERVER_TCP_ENABLED=on \
  -e SRS_RTC_SERVER_TCP_LISTEN=8080 \
  -e SRS_RTC_SERVER_PROTOCOL=tcp \
  registry.cn-hangzhou.aliyuncs.com/ossrs/srs:v5.0.60

如果是非localhost推流,得使用HTTPS,所以可以默認(rèn)使用TCP(8088),啟動(dòng)命令如下:

docker run --rm -it -p 8088:8088/tcp \
  -e CANDIDATE="192.168.3.82" \
  -e SRS_VHOST_RTC_RTC_TO_RTMP=on \
  -e SRS_HTTP_API_LISTEN=8080 \
  -e SRS_HTTP_API_HTTPS_ENABLED=on \
  -e SRS_HTTP_API_HTTPS_LISTEN=8088 \
  -e SRS_HTTP_SERVER_HTTTPS_ENABLED=on \
  -e SRS_RTC_SERVER_TCP_ENABLED=on \
  -e SRS_RTC_SERVER_TCP_LISTEN=8088 \
  -e SRS_RTC_SERVER_PROTOCOL=tcp \
  registry.cn-hangzhou.aliyuncs.com/ossrs/srs:v5.0.60

Note: 可以換成IP訪問(wèn)。注意由于是自簽名證書(shū),所以需要點(diǎn)擊下空白處,然后敲入字符串thisisunsafe

上面是通過(guò)環(huán)境變量配置的SRS,如果你習(xí)慣配置文件,也是可以的,和WebRTC over TCP相關(guān)的詳細(xì)配置如下:

rtc_server {
    # For WebRTC over TCP directly, not TURN, see https://github.com/ossrs/srs/issues/2852
    # Some network does not support UDP, or not very well, so we use TCP like HTTP/80 port for firewall traversing.
    tcp {
        # Whether enable WebRTC over TCP.
        # Overwrite by env SRS_RTC_SERVER_TCP_ENABLED
        # Default: off
        enabled off;
        # The TCP listen port for WebRTC. Highly recommend is some normally used ports, such as TCP/80, TCP/443,
        # TCP/8000, TCP/8080 etc. However SRS default to TCP/8000 corresponding to UDP/8000.
        # Overwrite by env SRS_RTC_SERVER_TCP_LISTEN
        # Default: 8000
        listen 8000;
    }
    # The protocol for candidate to use, it can be:
    #       udp         Generate UDP candidates. Note that UDP server is always enabled for WebRTC.
    #       tcp         Generate TCP candidates. Fail if rtc_server.tcp(WebRTC over TCP) is disabled.
    #       all         Generate UDP+TCP candidates. Ignore if rtc_server.tcp(WebRTC over TCP) is disabled.
    # Note that if both are connected, we will use the first connected(DTLS done) one.
    # Overwrite by env SRS_RTC_SERVER_PROTOCOL
    # Default: udp
    protocol udp;
}

我們上面演示的是和HTTP復(fù)用端口,使用獨(dú)立的TCP端口也是完全沒(méi)問(wèn)題的,具體可以自己嘗試了。

Future Plan

飯一口口吃,路一步步走,代碼一行行碼;SRS歡迎大家貢獻(xiàn)和參與,我們的深度開(kāi)發(fā)者社區(qū)人越來(lái)越多了,已經(jīng)達(dá)到了近50個(gè)深度定制SRS的開(kāi)發(fā)者。

如果你在2013年錯(cuò)過(guò)了給SRS貢獻(xiàn)RTMP,在2014年錯(cuò)過(guò)了貢獻(xiàn)Edge集群,在2015年錯(cuò)過(guò)了貢獻(xiàn)FLV,在2016年錯(cuò)過(guò)了貢獻(xiàn)DVR,在2017年錯(cuò)過(guò)了MP4和DASH,在2018年錯(cuò)過(guò)了貢獻(xiàn)Origin集群,在2019年錯(cuò)過(guò)了貢獻(xiàn)Docker化和云原生,在2020年錯(cuò)過(guò)了SRT和WebRTC,在2021年錯(cuò)過(guò)了HLS集群,在2022年錯(cuò)過(guò)了新官網(wǎng)和SRT協(xié)程化。。。

今天,你又錯(cuò)過(guò)了貢獻(xiàn)WebRTC over TCP,我和李鵬(TOC)花了兩個(gè)下午搞定了;另外,也特別感謝夏立新(TOC)的預(yù)研,節(jié)省了我們不少時(shí)間。其實(shí)貢獻(xiàn)并不難,難的是克服自己的慣性啊。

縱然有一萬(wàn)個(gè)不貢獻(xiàn)的理由,對(duì)于程序員來(lái)說(shuō),有一個(gè)貢獻(xiàn)的理由就夠了:作為程序員,只白嫖開(kāi)源卻不曾貢獻(xiàn),和咸魚(yú)又有何分別?!

你打算在2022年尾巴上錯(cuò)過(guò)貢獻(xiàn)什么?還有4個(gè)月時(shí)間,我們就要凍結(jié)5.0的功能開(kāi)發(fā)了,趕緊加入我們吧,還有非常多有意思又有價(jià)值的功能,等著你來(lái)一起完成。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容