Written by Winlin, 李鵬
在很多網(wǎng)絡(luò)條件下,WebRTC不適合使用UDP傳輸学辱,因此支持TCP傳輸是極其重要的能力乘瓤;而且SRS支持的是直接TCP傳輸?shù)姆绞交沸危苊馐褂肨URN中轉(zhuǎn)帶來的額外網(wǎng)絡(luò)層問題;這對于LoadBalancer也是非常友好的衙傀,一般支持TCP會更友好抬吟。
Why Important?
大約兩年前SRS支持了WebRTC,雖然支持了不少功能但還不夠完善统抬,這兩年收到了很多反饋火本,其中常見的而且非常重要的有:
- 用不了UDP,可能是公司網(wǎng)絡(luò)封掉了UDP協(xié)議聪建,或者封掉了小于10000的UDP端口钙畔,總之各種不可用的場景,SRS有個小工具檢測UDP端口可用性金麸,請參考#2843擎析。
- 媒體協(xié)議和端口太多了,TCP有RTMP(1935)和HTTP(80/443)挥下,UDP有WebRTC(8000)和SRT(10080)揍魂,還有HTTP API端口(1985),如何讓協(xié)議端口更收斂棚瘟?多開一個端口就多一份麻煩现斋。HTTP API和Stream使用同樣端口的問題,請參考#2881偎蘸。
- UDP可用但丟包比較嚴(yán)重步责,有可能是系統(tǒng)設(shè)置問題,也有可能是網(wǎng)絡(luò)設(shè)備或環(huán)境導(dǎo)致丟包禀苦,往往TCP是沒問題的蔓肯,請參考#2852
如果SRS能像HTTP-FLV那樣,在HTTP(80)端口傳輸媒體數(shù)據(jù)振乏,那該多么簡單蔗包?多么可靠啊慧邮!只要能上網(wǎng)调限,HTTP(80)端口就一定是可用的。流傳輸圖如下:
Publisher --------RTC------> SRS --------RTC--------> Player
(over TCP/80) (over TCP/80)
Note: 實(shí)際上WebRTC是有個API請求的误澳,所以這里還省略了HTTP API請求耻矮,可以在同樣端口上傳輸HTTP API,HTTP Stream和WebRTC數(shù)據(jù)忆谓。
專業(yè)人士一般會說:這個問題可以用TURN解決裆装,流傳輸圖如下:
Publisher -----> TURN ----> SRS -----> TURN -----> Player
(over TURN/3478). (over TURN/3478)
TURN的方案明顯是不好的,有幾個問題:
- 多引入了一個網(wǎng)元,需要額外考慮部署和依賴問題哨免,而且有些TURN可能還沒提供Docker茎活。
- 多引入了一個協(xié)議,看起來簡單的協(xié)議(幾個交互)琢唾,如何監(jiān)控和排查問題载荔,如何運(yùn)維都是非常麻煩的。
- 延遲和成本問題采桃,多一跳就多一次延遲懒熙,多一份網(wǎng)元就多一個集群,這都是真金白銀的CPU消耗普办。
因此工扎,WebRTC支持TCP傳輸,最好的方案是直接TCP傳輸而不是TURN協(xié)議泌豆,參考以下兩個RFC:
- SDP and ICE: TCP Candidates with Interactive Connectivity Establishment (ICE)
- RTP over TCP: Framing RTP and RTCP Packets over Connection-Oriented Transport
下面介紹下SRS目前的進(jìn)展。
What's Now?
SRS 5.0正式解決了這個問題:
- HTTP API吏饿、HTTP Stream踪危、WebRTC over TCP,可以全部復(fù)用一個TCP端口猪落,比如HTTPS(443)贞远。
- 支持直接UDP或TCP傳輸,不依賴TURN協(xié)議笨忌,沒有額外的網(wǎng)元蓝仲,沒有額外部署和資源消耗。
- 可部署在LoadBalancer后面(已實(shí)現(xiàn))官疲,可配合Proxy(未實(shí)現(xiàn))或者Cluster(未實(shí)現(xiàn))實(shí)現(xiàn)負(fù)載均衡和擴(kuò)容袱结。
Note: 注意需要升級到
v5.0.60+
,若使用Docker也請先確認(rèn)SRS的版本途凫。
我們先看最簡單情況垢夹,用一個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
- 推流(WebRTC over TCP): webrtc://localhost:8080/live/livestream
- 播放(WebRTC over TCP): webrtc://localhost:8080/live/livestream
一般需要支持直播维费,所以下面果元,只用一個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
- 推流(WebRTC over TCP): webrtc://localhost:8080/live/livestream
- 播放(WebRTC over TCP): webrtc://localhost:8080/live/livestream
- 播放(HTTP FLV): http://localhost:8080/live/livestream.flv
- 播放(HLS): http://localhost:8080/live/livestream.m3u8
如果是非localhost
推流犀盟,得使用HTTPS而晒,所以可以默認(rèn)使用TCP(8088),啟動命令如下:
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
- 推流(WebRTC over TCP): webrtc://localhost:8088/live/livestream
- 播放(WebRTC over TCP): webrtc://localhost:8088/live/livestream
- 播放(HTTP FLV): https://localhost:8088/live/livestream.flv
- 播放(HLS): https://localhost:8088/live/livestream.m3u8
Note: 可以換成IP訪問阅畴。注意由于是自簽名證書倡怎,所以需要點(diǎn)擊下空白處,然后敲入字符串
thisisunsafe
上面是通過環(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端口也是完全沒問題的焦匈,具體可以自己嘗試了血公。
Future Plan
飯一口口吃,路一步步走缓熟,代碼一行行碼累魔;SRS歡迎大家貢獻(xiàn)和參與,我們的深度開發(fā)者社區(qū)人越來越多了够滑,已經(jīng)達(dá)到了近50個深度定制SRS的開發(fā)者垦写。
如果你在2013年錯過了給SRS貢獻(xiàn)RTMP,在2014年錯過了貢獻(xiàn)Edge集群彰触,在2015年錯過了貢獻(xiàn)FLV梯投,在2016年錯過了貢獻(xiàn)DVR,在2017年錯過了MP4和DASH况毅,在2018年錯過了貢獻(xiàn)Origin集群分蓖,在2019年錯過了貢獻(xiàn)Docker化和云原生,在2020年錯過了SRT和WebRTC尔许,在2021年錯過了HLS集群么鹤,在2022年錯過了新官網(wǎng)和SRT協(xié)程化。味廊。蒸甜。
今天,你又錯過了貢獻(xiàn)WebRTC over TCP余佛,我和李鵬(TOC)花了兩個下午搞定了柠新;另外,也特別感謝夏立新(TOC)的預(yù)研辉巡,節(jié)省了我們不少時(shí)間登颓。其實(shí)貢獻(xiàn)并不難,難的是克服自己的慣性啊红氯。
縱然有一萬個不貢獻(xiàn)的理由框咙,對于程序員來說,有一個貢獻(xiàn)的理由就夠了:作為程序員痢甘,只白嫖開源卻不曾貢獻(xiàn)喇嘱,和咸魚又有何分別?塞栅!
你打算在2022年尾巴上錯過貢獻(xiàn)什么者铜?還有4個月時(shí)間,我們就要凍結(jié)5.0的功能開發(fā)了,趕緊加入我們吧作烟,還有非常多有意思又有價(jià)值的功能愉粤,等著你來一起完成。