simpleWebrtc 架設方案

近期架設一次webrtc另一種開源實現simplewebrtc用於學習webrtc整體實現及架構。現在單純P2P架構的webrtc開源服務器已經很少了且近乎沒有維護。大部分都是Webrtc SFU和MCU網絡模型實現,但對於物聯網設備一般情況下下都是一對一通話且P2P十分重要(轉發服務器開銷很大)。

開源實現裏面稍微靠譜一點就是SimpleWebrtc方案了,但該方案也在18年中旬停止維護了,今天部署發現也是一堆坑。

本文基於ubuntu環境架設


1 Webrtc 鏈接建立流程

這裏引用一下網易雲信的架構圖及基礎流程說明來對webrtc鏈接建立進行介紹
image.png
1) WebRTC A通過Signal Server轉發SDP OFFER到WebRTC B。WebRTC B做完本地處理以後,通過 Signal Server轉發SDP ANSWER到A。
2)A、B同時向STUN Server發送Binding request請求自身的外網地址,並從STUN Server回包的MAPPED-ADDRESS中得到各自的外網地址;
3)A、B收集完內外網ICE Candidate,並通過Signal Server發送給對方;
4)雙方開始做NAT穿越,互相給對方的ICE Candidate發送STUN Binding Request;
5)NAT穿越成功,A、B之間的P2P連接建立,進入媒體互通階段。

從上文流程描述上既可以看到有三種角色參與webrtc通信流程,一般情況下可以理解爲由三個部分組成:
STUN/TURN Server
Signal Server
WebRTC Client端(App Server)

信令服務器中需要配置turn 和stun 地址。stun 可以獲取NAT後的地址從而建立連接,turn 可以在打洞失敗情況下通過服務器轉發保證功能正常, ice 是一個框架,可以包含 turn或stun等穿透協議。具體參考STUN, TURN, ICE介紹。
simplewebrtc 是一套webrtc 開源方案提供了WebRTC Client Server及信令服務器,使用它即可實現一個簡單demo,並通過閱讀實現流程,可熟悉webrtc通信建立過程。

2 架設過程

本文基於simplewebrtc進行架設,
打洞服務器:開源coturn 項目地址:https://github.com/coturn/coturn
信令服務器:simplewebrtc配套的signalmaster ** 項目地址:https://github.com/andyet/signalmaster
Web APP
simplewebrtc ** ** 項目地址:**https://github.com/andyet/SimpleWebRTC

2.1 coturn 服務器架設

P2P連接建立會涉及到三個概念:STUN, TURN,ICE

  • STUN(Session

    Traversal Utilities for NAT,NAT會話穿越應用程序)是一種網絡協議,它允許位於NAT(或多重NAT)後的客戶端找出自己的公網地址,查出自己位於哪種類型的NAT之後以及NAT爲某一個本地端口所綁定的Internet端端口。這些信息被用來在兩個同時處於NAT路由器之後的主機之間創建UDP通信。該協議由RFC 5389定義。
  • TURN(全名Traversal Using Relay NAT),是一種數據傳輸協議(data-transfer protocol)。允許在TCP或UDP的連在線跨越NAT或防火牆。TURN是一個client-server協議。TURN的NAT穿透方法與STUN類似,都是通過獲取應用層中的公有地址達到NAT穿透。但實現TURN

    client的終端必須在通信開始前與TURN server進行交互,並要求TURN server產生"relay

    port",也就是relayed-transport-address。這時TURN server會創建peer,即遠程端點(remote

    endpoints),開始進行中繼(relay)的動作,TRN

    client利用relay port將數據發送至peer,再由peer轉傳到另一方的TURN client。
  • ICE 是一個用於在offer/answer模式下的NAT傳輸協議,主要用於UDP下多媒體會話的建立,其使用了STUN協議以及TURN 協議,同時也能被其他實現了offer/answer模型的的其他程序所使用,比如SIP(Session Initiation Protocol).

而coturn即由Google開源方案發展而來TURN和STUN
Server的免費開源實現。

安裝

sudo apt-get install coturn

生成tls證書
因爲coturn可以支持tls 所以這裏需要生成一份用於tls通信的證書及密匙。

mkdir  pem
openssl req -x509 -newkey rsa:2048 -keyout ./pem/turn_server_pkey.pem -out ./pem/turn_server_cert.pem -days 1095 -nodes

-days 有效天數
-node 不加密密匙 加密密匙後則需要解壓密碼,需要填入部分信息,然後得到證書和密匙:turn_server_pkey.pem turn_server_cert.pem

編輯文件/etc/turnserver.conf配置TURN服務器。並將下下列配置相應修改後複製到文檔末尾保存退出
下面配置參數在該文件中均有註釋說明。可自行搜索閱讀。

listening-device=eth0
listening-port=3478
tls-listening-port=5349
listening-ip=172.17.19.101
relay-device=eth0
relay-ip=172.17.19.101
external-ip=60.70.80.91/172.17.19.101
min-port=49152
max-port=65535
fingerprint
lt-cred-mech
realm=demo
use-auth-secret
static-auth-secret=12345
stale-nonce
cert=/home/usera/coturn/pem/turn_server_cert.pem
pkey=/home/usera/coturn/pem/turn_server_pkey.pem
no-loopback-peers
no-multicast-peers
mobility
no-cli

這裏通過上訴使用到參數的相應註釋可對照參考

listening-device=eth0           #本地監聽網卡
listening-port=3478             #監聽端口
tls-listening-port=5349        #tls監聽端口 
listening-ip=172.17.19.101   #監聽內網ip 如果本身網卡綁定的公網ip 則填爲公網ip,若爲AWS 阿里雲等雲主機則爲內網ip
relay-device=eth0                # 本地用於轉發的網卡設備    
relay-ip=172.17.19.101       #Relay 地址,用於turn服務器在穿透失敗的情況下用於轉發地址
external-ip=60.70.80.91/172.17.19.101      #如果是雲主機 則需配置這樣 且爲雲主機公網ip/內網ip 
min-port=49152                #relay用於轉發端口 最小值   雲主機 注意開安全組/防火牆 
max-port=65535               #relay用於轉發端口 最大值  默認端口範圍爲49152 and 65535
fingerprint                            # turn 消息中使用指紋進行消息驗證
lt-cred-mech                        #使用長期憑證機制 需要支持WebRTC服務器coTurn必須開啓長期憑證機制
realm=demo                       #管理員用戶登錄域  必須用長期憑證機制或轉變爲REST API。
use-auth-secret                   # TURN REST API flag.  設置基於身份驗證密匙的特殊授權選項的標誌。、
static-auth-secret=north  # 僅用於turn rest api的“static”身份驗證機密值(字符串)
stale-nonce                        #session壽命,默認爲無限時間,配置後爲600s
pkey-pwd =                     #密匙解壓密碼
cert=/home/ubuntu/pem/turn_server_cert.pem    #tls 證書路徑
pkey=/home/ubuntu/pem/turn_server_pkey.pem #tls 密匙路徑 
no-loopback-peers                       #禁用peer 迴環地址 如(127.x.x.x and ::1).
no-multicast-peers                        #禁用peer 已知廣播地址(224.0.0.0 and above, and FFXX:*).
mobility                                         #Mobility with ICE , MICE規格支持.  peer在網絡之間移動時,端點必須更改其IP地址。 MICE即爲解決該情況的方案
no-cli                                          #關閉turn 服務Cli支持

這裏因爲signalmaster信令服務器使用turn rest API 靜態身份驗證方式 與apprtc 有一定差異。所以直接配置的是use-auth-secret 和static-auth-secret=north 這兩個參數而不是配置user=demo:12345 這種驗證方式。

啓動

啓動及查看狀態

先使用命令啓動

sudo /usr/bin/turnserver -c /etc/turnserver.conf  -o -v

守護啓動:
修改 /etc/default/coturn,把TURNSERVER_ENABLED=1的註釋去掉。

sudo systemctl daemon-reload
sudo service coturn start

查看狀態

service coturn status

image.png

測試

如果在雲主機上運行請確認相應端口安全組已開放 比如實例中的3478
5349 的TCP UDP端口

測試STUN:

turnutils_stunclient -p 3478 60.70.80.91
  • 3478是STUN服務的監聽端口
  • 60.70.80.91是啓動STUN服務的IP地址

結果如下:這裏能看到 UDP
reflexive addr 爲當前網絡的出口IP及端口

0: IPv4. UDP reflexive addr: 101.204.xxx.xxx:60040

測試TURN:

turnutils_uclient -v -t -T -W 12345 54.222.207.42

使用靜態密碼進行鏈接測試
-W:TURN REST API “plain text” secret.
這兩個參數需與coturn中static-auth-secret保持一致

測試成功後打印類似於下面內容:

4: start_mclient: tot_send_msgs=10, tot_recv_msgs=10
4: start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000
4: Total transmit time is 3
4: Total lost packets 0 (0.000000%), total send dropped 0 (0.000000%)
4: Average round trip delay 68.300000 ms; min = 36 ms, max = 104 ms
4: Average jitter 24.000000 ms; min = 17 ms, max = 64 ms

到這裏coturn部署完畢。

說明

1 作爲turn/stun服務器對外提供服務器則肯定會涉及到身份驗證相關內容,一種方案是使用使用數據庫存儲用戶或Restful API向自有賬戶服務器驗證。第二種就是簡單粗暴設置密碼驗證。
2 在一些文章提到turnadmin 創建管理員賬戶
sudo turnadmin -a -u
用戶名 -p 密碼 -r 域名
因爲coTurn還提供了一個HTTPS頁面:可以進行一些系統設置,比如修改領域,查看用戶等,admin用戶就是用來訪問這個頁面。所以不需要的情況下不用執行該步驟。
3 coturn性能
coturn當用作ICE解決方案的一部分時,對於VoIP連接,此TURN服務器可以處理每個CPU的數千個同時呼叫(當使用TURN協議時)或僅使用STUN協議時的數萬個呼叫。對於幾乎無限的可擴展性,可以使用負載平衡方案。可以使用以下工具(一個或它們的組合)實現負載平衡:該方案由谷歌開源發展而來

2.2 信令服務器signalmaster

signalmaster 一個簡單的信令服務器,供客戶端連接併爲WebRTC進行信令。

安裝

本節需要node環境,因signalmaster 同樣長期未維護,所以需要node版本降到8.16.0,且package.json中socket.io版本也需要修改爲1.37

安裝node環境並降級

apt install nodejs    #下載nodejs
nodejs -v             #查看版本
apt install npm       #下載npm 工具
sudo npm install -g n #下載node 版本管理工具n
n list                #查看有哪些版本可用 
sudo n  8.16.0        #切換版本到8.16.0
node -v               #查看版本,如果沒有更新到,可以刪掉原文件,手動把n模塊安裝的node鏈接過去。
sudo ln -s /usr/local/bin/node /usr/bin/node  #版本已經切換成功可不執行這步

下載signalmaster並配置依賴

git clone https://github.com/andyet/signalmaster.git # 下載源碼
vi package.json   # 修改依賴 修改socket io版本爲1.3.7
npm install     #安裝依賴  確保當前node版本爲8.16.0

配置signalmaster 參數
修改config/development.json 配置 支持ssl 及 stun 配置

"server": {
   "port": 8888,
   "/* secure */": "/* whether this connects via https */",
   "secure": true,
   "key": "/home/usera/certs/webrtc.xxxx.top.key",
   "cert": "/home/usera/certs/webrtc.xxxx.top.pem",
   "password": null
 },
 "rooms": {
   "/* maxClients */": "/* maximum number of clients per room. 0 = no limit */",
   "maxClients": 0
 },
 "stunservers": [
   {
     "urls": "stun::60.70.80.91:3478"
   }
 ],

 "turnservers": [
   {
     "urls": ["turn:60.70.80.91:3478"],
     "secret": "12345",
     "expiry": 86400
   }
  • Secure 是否支持ssl
  • Key 證書密匙路徑
  • Cert 證書路徑
  • Stunservers stun服務器地址
  • Turnservers turn服務器地址
  • turn服務器身份驗證:secret 爲turn服務器中設置的靜態密碼 如:static-auth-secret=12345

這裏如果不配置這些參數,會導致信令報錯。建議直接使用域名加證書的方式啓動信令服務器

啓動

npm start

打印

&yet -- signal master is running at: http://localhost:8888

說明啓動成功。

測試

http://localhost:8888/socket.io/

訪問地址得到下列放回即爲部署成功。PS:雲主機中則需要開啓8888端口及用雲主機ip替換掉localhost。
返回如下 內容signal master 已經工作起來

{"code":0,"message":"Transport unknown"}

說明

node版本不降 會導致錯誤:
validation.target.mk:102:
recipe for target ‘Release/obj.target/validation/src/validation.o’ failed
Socket.io使用最新版會導致
TypeError: Cannot read
property ‘resources’ of undefined

2.3 SimpleWebrtc

安裝

下載源碼安裝依賴

git clone https://github.com/andyet/SimpleWebRTC.git  #下載源碼
npm install                                           #安裝依賴

修改源碼
修改simplewebrtc-with-adapter.bundle.js:

vi out/simplewebrtc-with-adapter.bundle.js

反向搜索url參數: SimpleWebRTC 構造函數中this.config中 修改url爲信令服務器地址
搜索iceServer參數修改爲2.1中coturn地址: iceServers: [{‘urls’: ‘stun:地址:3478’}]

修改test/index.html :

vi test/index.html

test/index.html 中引用了Google路徑Jquery代碼,國內無法訪問會導致界面卡住。可以將這個JQuery 在線引用改爲百度cdn地址
將地址:
https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js 改爲https://libs.baidu.com/jquery/1.9.0/jquery.min.js

修改package.json:
將scripts 中 test-page 中stupid-server -s 後加入證書及密匙路徑 以支持https。

stupid-server -s  -c /home/usera/certs/webrtc.xxx.top.pem  -k /home/usera/certs/webrtc.xxx.top.key  -h 0.0.0.0

啓動

npm run test-page

打印以下內容啓動成功:
open https://0.0.0.0:8443/test/
Listening on 0.0.0.0:8443…

測試

兩端使用筆記本和手機進行測試,均使用firefox瀏覽器測試

https://60.70.80.91:8443/test/

填入公網ip訪問 ,請填入自己雲服務器公網ip。這裏可能會報證書錯誤,適應被沒有配置ssl證書 直接忽略警告繼續訪問。
兩端填入同一房間建立鏈接
測試效果如下:
建立鏈接前:
Screenshot_2019-06-05-14-58-53-098_org.mozilla.firefox.png
建立鏈接後:
Screenshot_2019-06-06-11-20-02-137_org.mozilla.firefox.png

說明

默認設置情況下每路碼流碼流大約在2Mbps,網絡較好情況下,時延在300~400ms(p2p - relay)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章