1.WebRTC后台服務:
-
通話的房間服務器(Room Server)
房間服務器是用來創建和管理通話會話的狀態維護,是雙方通話還是多方通話,加入與離開房間等等,我們暫時沿用Google部署在GAE平台上的AppRTC這個房間服務器實現,該GAE App的源碼可以在github.com上獲取.該實現是一個基於Python的GAE應用,我們需要下載Google GAE的離線開發包到我們自己的Linux服務器上來運行該項目,搭建大陸互聯網環境下的房間服務器.
-
通話的信令服務器(Signaling Server)
信令服務器是用來管理和協助通話終端建立去中心的點對點通話的一個角色.這個角色要負責一下任務:
1. 用來控制通信發起或者結束的連接控制消息
2. 發生錯誤時用來相互通告的消息
3. 各自一方媒體流元數據,比如像解碼器、解碼器的配置、帶寬、媒體類型等等
4. 兩兩之間用來建立安全連接的關鍵數據
5. 外界所能看到的網絡上的數據,比如廣域網IP地址、端口等
信令服務器的具體協議實現沒有嚴格規定,只要實現功能就OK.
我們這里依然沿用Google提供的基於GO語言和WebSocket的信令服務器Collider.和上面的房間服務器一並在Github上可以獲取.獲取到我們自己的Linux服務器上用GO語言的運行環境來運行該信令服務器.
-
防火牆打洞服務器(STUN/TURN/ICE Server)
我們目前大部分人連接互聯網時都處於防火牆后面或者配置私有子網的家庭(NAT)路由器后面,這就導致我們的計算機的IP地址不是廣域網IP地址,故而不能相互之間直接通訊. 正因為這樣的一個場景,我們得想辦法去穿越這些防火牆或者家庭(NAT)路由器,讓兩個同處於私有網絡里的計算機能夠通訊起來.
STUN(Simple Traversal of UDP over NATs,NAT 的UDP簡單穿越); STUN協議服務器就是用來解決這些問題:
-
探測和發現通訊對方是否躲在防火牆或者NAT路由器后面.
-
確定內網客戶端所暴露在外的廣域網的IP和端口以及NAT類型等信息;STUN服務器利用這些信息協助不同內網的計算機之間建立點對點的UDP通訊.
STUN協議可以很好的解決一般家用(NAT)路由器環境的打洞問題,但是對於大部分的企業的網絡環境就不是很好了.
這時需要一個新的解決方案:TURN(Traversal Using Relay NAT,允許在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)的動作,TURN client利用relay port將資料傳送至peer,再由peer轉傳到另一方的TURN client.通過服務器新產生的peer來進行數據的中轉.
ICE協議就是綜合前面2種協議的綜合性NAT穿越解決方案.
通過offer/answer模型建立基於UDP的通訊。ICE是offer/answer模型的擴展,通過在offer和answer的SDP(Session Description Protocol)里面包含多種IP地址和端口,然后對本地SDP和遠程SDP里面的IP地址進行配對,然后通過P2P連通性檢查進行連通性測試工作,如果測試通過即表明該傳輸地址對可以建立連接。其中IP地址和端口(也就是地址)有以下幾種:本機地址、通過STUN服務器反射后獲取的server-reflexive地址(內網地址被NAT映射后的地址)、relayed地址(和TURN轉發服務器相對應的地址)及Peer reflexive地址等。
2.房間服務器與信令服務器搭建:
我們把這一系列后台服務器搭建在公網的一個Ubuntu Linux服務器中.
服務器的代碼我們選用GoogleChrome的開源項目,該項目可以在Github找到:
https://github.com/GoogleChrome/webrtc
該項目的一些示例可以在下面網址得到:
http://googlechrome.github.io/webrtc/
在我們自己的服務器中運行Google的房間服務器AppRTC需要依賴 Google App Engine SDK for Python 和 Grunt.
先搭建房間服務器AppRTC
- 首先我們安裝Grunt:
cheetah@localhost:~/$ sudo apt-get install npm cheetah@localhost:~/$ sudo apt-get install nodejs-legacy cheetah@localhost:~/$ sudo npm -g install grunt-cli
- 下載該項目的源碼到某個目錄:
cheetah@localhost:~/$ cd ~; cheetah@localhost:~/$ git clone https://github.com/GoogleChrome/webrtc.git;
- 終端Shell切換當前工作目錄到上一步的下載的項目目錄webrtc下,然后安裝Grunt以及Grunt的依賴:
cheetah@localhost:~/$ cd webrtc; cheetah@localhost:~/webrtc$ npm install;
- 運行AppRTC房間服務器之前我們需要Grunt編譯一下該項目的js文件之類:
cheetah@localhost:~/webrtc$ grunt;
上面的編譯過程會自動下載安裝Google App Engine SDK至當前目錄.
cheetah@localhost:~/webrtc$ ls bower.json google_appengine Gruntfile.js LICENSE.md README.md samples build google_appengine_1.9.17.zip images node_modules run_python_tests.py webtest-master CONTRIBUTING.md grunt-chrome-build index.html package.json run_python_tests.sh webtest-master.tar.gz
下一步,我們需要把Google App Engine SDK的目錄加入系統環境變量$PATH
,並使之生效.
cheetah@localhost:~/webrtc$ echo "export PATH=$PATH:$PWD/google_appengine" > ~/.bash_profile cheetah@localhost:~/webrtc$ source ~/.bash_profile
這個時候我們就可以直接運行我們的房間服務器AppRTC了.用下面的命令來開啟(主機名:vpn.wuqiong.tk可以用自己的給我錢IP地址代替):
cheetah@localhost:~/webrtc$ dev_appserver.py --host vpn.wuqiong.tk samples/web/content/apprtc/
再搭建信令服務器
信令服務器我們依然采用Google Chrome WebRTC項目里提供的用GO語言編寫的基於websocket的信令服務器:Collider.
我們需要先安裝Go語言運行環境支持:
cheetah@localhost:~/webrtc$ sudo apt-get install golang-go
然后在我們的用戶目錄新建一個目錄(collider_root)來存放這個Collider的go代碼程序.
cheetah@localhost:~/webrtc$ mkdir -p ~/collider_root; cheetah@localhost:~/webrtc$ export COLLIDER_ROOT=$HOME/collider_root; //也可以加入~/.bash_profile
下一步就是鏈接wenrtc項目目錄下面的collider代碼目錄到$COLLIDER_ROOT/src下去,准備后續的編譯工作;
cheetah@localhost:~/webrtc$ ln -sf $PWD/samples/web/content/apprtc/collider/collider $COLLIDER_ROOT/src/ cheetah@localhost:~/webrtc$ ln -sf $PWD/samples/web/content/apprtc/collider/collidermain $COLLIDER_ROOT/src/ cheetah@localhost:~/webrtc$ ln -sf $PWD/samples/web/content/apprtc/collider/collidertest $COLLIDER_ROOT/src/
一切准備之后,我們就主要編譯安裝Collider了:
cheetah@localhost:~/webrtc$ go get collidermain cheetah@localhost:~/webrtc$ go install collidermain
這個時候,信令服務器的二進制程序就安裝到了$COLLIDER_ROOT/bin下去了. 如下命令就可以開啟運行信令服務器:
cheetah@localhost:~/webrtc$ $COLLIDER_ROOT/bin/collidermain -port=8089 -tls=false
信令服務器暫時用非tls方式運行.因為我們自簽名的證書Websocket通訊不了.
3.STUN/TURN/ICE服務器的搭建
我們選擇有更豐富功能的coTurn作為我們的NAT穿越打洞服務器,該項目是一個C/C++語言的開源項目,項目地址: https://code.google.com/p/coturn/ 或者我們直接下載已經編譯好的軟件包,在下面站點可以下載我們對應平台的軟件包: http://turnserver.open-sys.org/downloads/v4.4.1.2/ 打開這個網址,根據我們的服務器類型選擇下載,我現在選擇Debian和Ubuntu系統的包:
cd ~; wget http://turnserver.open-sys.org/downloads/v4.4.1.2/turnserver-4.4.1.2-debian-wheezy-ubuntu-mint-x86-64bits.tar.gz
接着解壓軟件包:
tar xvfz turnserver-4.4.1.2-debian-wheezy-ubuntu-mint-x86-64bits.tar.gz
詳細閱讀安裝手冊 INSTALL
文件,根據指導進行安裝:
$ sudo apt-get update $ sudo apt-get install gdebi-core $ sudo gdebi coturn*.deb
然后編輯配置文件,打開系統默認啟動配置:
$ vim /etc/default/coturn
把上面打開編輯的文件中的這一行TURNSERVER_ENABLED=1
去掉注釋,保存退出.
再根據實際情況編輯coturn的配置文件 /etc/turnserver.conf
,比如我打開的配置項如下:
listening-device=eth0 listening-ip=~~106.186.127.xxx~~ relay-device=eth0 relay-ip=~~106.186.127.xxx~~ Verbose fingerprint lt-cred-mech use-auth-secret static-auth-secret=diveinedu user=diveinedu:0x06b2afcf07ba085b7777b481b1020391 user=diveinedu:diveinedu stale-nonce cert=/etc/turn_server_cert.pem pkey=/etc/turn_server_pkey.pem no-loopback-peers no-multicast-peers sha256 mobility no-cli
上面cert和pkey配置的自簽名證書用Openssl命令生成:
sudo openssl req -x509 -newkey rsa:2048 -keyout /etc/turn_server_pkey.pem -out /etc/turn_server_cert.pem -days 99999 -nodes
穿牆服務器的一切配置完成之后, 萬事俱備,之前啟動命令了:
service coturn start;
房間服務器和信令服務器的設置
三個服務器都搭建完成之后,我們需要多一定的整合配置,使他們能一起工作: apprtc目錄下的constants.py是一些常量配置信息的配置文件,比如我的做了如下設置:
#TURN_BASE_URL = 'https://computeengineondemand.appspot.com' TURN_BASE_URL = 'http://apprtc.diveinedu.com' #TURN_URL_TEMPLATE = '%s/turn?username=%s&key=%s' TURN_URL_TEMPLATE = '%s/turn.php?username=%s&key=%s' #CEOD_KEY = '4080218913' CEOD_KEY = 'diveinedu' #WSS_HOST_PORT_PAIR = 'apprtc-ws.webrtc.org:443' WSS_HOST_PORT_PAIR = 'apprtc.diveinedu.com:8089'
由於我們的信令服務器沒有開啟安全Socket模式,所以我們要對應的改一下apprtc的代碼, 做apprtc.py中如下修改:
def get_wss_parameters(request): ws_host_port_pair = request.get('wshpp') ws_tls = request.get('wstls') if not ws_host_port_pair: ws_host_port_pair = constants.WSS_HOST_PORT_PAIR if ws_tls and ws_tls == 'false': wss_url = 'ws://' + ws_host_port_pair + '/ws' wss_post_url = 'http://' + ws_host_port_pair else: wss_url = 'ws://' + ws_host_port_pair + '/ws' wss_post_url = 'http://' + ws_host_port_pair return (wss_url, wss_post_url)
把原來的wss和https的scheme都改為ws和http,不要讓客戶端或者瀏覽器去使用SSL鏈接.當然,如果有第三方根證書的簽名機構頒發的證書,那就不需要這樣了
而對應的信令服務器也需要稍微做設置: 編輯collider/collidermain/main.go,修改設置自己的房間服務器URL:
//var roomSrv = flag.String("room-server", "https://apprtc.appspot.com", "The origin of the room server") var roomSrv = flag.String("room-server", "http://apprtc.diveinedu.com:8080/", "The origin of the room server")
經過這一些簡單的房間服務器和信令服務器的定制設置之后,我們就搭建了一套基於Google項目的屬於自己的WebRTC的簡單服務了.
用谷歌瀏覽器打開 http://apprtc.diveinedu.com:8080/ ,注冊房間之后就可以視頻通話了.當然結合之前的WebRTC for iOS 框架就可以瀏覽器和iOS的原生應用直接視頻通話了.
本文檔由長沙戴維營教育整理。