webrtc服務器環境搭建
(基於公網環境)
Last Modified Date: 2017/8/2
https://blog.csdn.net/gladsnow/article/details/77900578
目錄
1. 搭建平台
2. 軟件安裝
3. 搭建房間服務器(Room Server)
4. 搭建信令服務器(Collider Server)
5. 搭建STUN\TURN服務器
6. 配置Nginx服務器
7. 運行測試
8. 附錄
1. 搭建平台
- 操作系統: Ubuntu 16.04 server(64bits)
- Google webrtc的服務器Demo:詳見https://github.com/webrtc/apprtc
- 域名: webrtc.olcms.com
- IP地址: 需要是公網地址
2. 軟件安裝
- 安裝JDK:
add-apt-repository ppa:openjdk-r/ppa
apt-get update
apt-get install openjdk-8-jdk
- 安裝nodejs相關包:
apt-get install nodejs
apt-get install npm
apt-get install nodejs-legacy
npm -g install grunt-cli
- 安裝Python和Python-webtest:
apt-get install python
apt-get install python-webtest
- 1
- 2
注: 若已安裝過上述軟件,可忽略;如上述未提及的軟件需要安裝,請自行安裝。
3. 搭建房間服務器(Room Server)
- 下載apprtc源碼(操作所在目錄/root/)
git clone https://github.com/webrtc/apprtc.git
cd apprtc
npm install
若npm install報錯,請自行解決。
- 修改文件
1.修改/root/apprtc/src/app_engine/constants.py
TURN_BASE_URL = 'https://webrtc.olcms.com'; #本機域名webrtc.olcms.com
TURN_URL_TEMPLATE = '%s/turn.php?username=%s&key=%s'; #如果turn.php未實現,可使用默認配置
CEOD_KEY = 'inesadt' #此處后面turn配置的用戶名保持一致
ICE_SERVER_BASE_URL = 'https://webrtc.olcms.com';
ICE_SERVER_URL_TEMPLATE = '%s/iceconfig.php?key=%s'; #如果iceconfig.php未實現,可用默認配置,但是Android Apk會有問題
WSS_INSTANCE_HOST_KEY = 'webrtc.olcms.com:8089' #信令服務器端口號8089
WSS_INSTANCE_NAME_KEY = 'vm_name'
WSS_INSTANCE_ZONE_KEY = 'zone'
WSS_INSTANCES = [{
WSS_INSTANCE_HOST_KEY: 'webrtc.olcms.com:8089',
WSS_INSTANCE_NAME_KEY: 'wsserver-std',
WSS_INSTANCE_ZONE_KEY: 'us-central1-a'
}, {
WSS_INSTANCE_HOST_KEY: 'webrtc.olcms.com:8089',
WSS_INSTANCE_NAME_KEY: 'wsserver-std-2',
WSS_INSTANCE_ZONE_KEY: 'us-central1-f'
}]
- 編譯(在apprtc目錄下進行)
grunt build
編譯完成之后,會生成out目錄,房間服務器編譯完成。
注(編譯成功可忽略):此處編譯需要翻牆,若編譯時無法翻牆,可下載手動下載https://api.callstats.io/static/callstats.min.js,並把文件callstats.min.js放到目錄/root/apprtc/out/app_engine/third_party/callstats/下。然后修改/root/apprtc/build/build_app_engine_package.py文件:
# Download callstats.
......
......
response = requests.get(urls[fileName])
#if response.status_code == 200: #把此處注釋掉
print 'Downloading %s to %s...' % (urls[fileName], path)
with open(path + fileName, 'w') as to_file:
to_file.write(response.text)
#else: #把此處注釋掉
# raise NameError('Could not download: ' + filename + ' Error:' + \ #把此處注釋掉
#str(response.status_code)) #把此處注釋掉
然后繼續進行編譯即可。
-
安裝和配置google app engine
1.下載google app engine
需翻牆,下載地址https://storage.googleapis.com/appengine-sdks/featured/google_appengine_1.9.50.zip),或者通過其他地方下載。2.配置google app engine 路徑
解壓google_appengine_1.9.50.zip
unzip google_appengine_1.9.50.zip
編輯/etc/profile文件,在文件最后添加語句:
export PATH="$PATH:/root/google_appengine/"
(當前安裝目錄是/root/google_appengine,請根據自己的安裝目錄進行配置)
保存profile文件,進行以下操作生效
source /etc/profile
- 運行房間服務器(room server)
在目錄/root/google_appengine目錄下找到dev_appserver.py腳本,執行以下語句
./dev_appserver.py --host=webrtc.olcms.com /root/apprtc/out/app_engine
若想后台運行,則執行
nohup ./dev_appserver.py --host=webrtc.olcms.com /root/apprtc/out/app_engine &
-
在瀏覽器中訪問房間服務器
4. 搭建信令服務器(Collider Server)
- 安裝go語言編譯器
apt-get install golang-go
- 1
- 復制collider源代碼
(此源碼在房間服務器源碼目錄下/root/apprtc/src/collider/)
在/root目錄下新建文件夾
mkdir -p goWorkspace/src
- 1
配置編譯環境,此配置是暫時有效的
export GOPATH=/root/goWorkspace/
- 1
把/root/apprtc/src/collider/目錄下的三個目錄(collider、collidermain、collidertest)復制到/root/goWorkspace/src/目錄下
cp -rf /root/apprtc/src/collider/* /root/goWorkspace/src
- 1
- 修改代碼
1.編輯文件/root/goWorkspace/src/collidermain/main.go,修改房間服務器的地址
var roomSrv = flag.String("room-server", "https://webrtc.olcms.com", "The origin of the room server")
- 1
2.編輯文件/root/goWorkspace/src/collider/collider.go,修改下面這句:
e = server.ListenAndServeTLS("/cert/cert.pem", "/cert/key.pem")
- 1
修改為
e = server.ListenAndServeTLS("/etc/letsencrypt/live/webrtc.olcms.com/fullchain.pem", "/etc/letsencrypt/live/webrtc.olcms.com/privkey.pem")
- 1
其中fullchain.pem和privkey.pem為SSL證書,具體證書路徑根據實際路徑進行配置,SSL證書生成見后續Nginx配置。
- 編譯信令服務器
進入目錄/root/goWorkspace/src/,此處編譯需要翻牆。
go get collidermain
go install collidermain
- 1
- 2
編譯成功后,在/root/goWorkspace/下會生成bin和pkg目錄。
若此處編譯時無法翻牆,可手動下載需要的文件。在/root/goWorkspace/src/目錄下,
mkdir -p golang.org/x
cd golang.org/x/
git clone https://github.com/golang/net
然后再進行編譯即可。
- 運行信令服務器
進入/root/goWorkspace/bin/目錄,運行信令服務器
./collidermain -port=8089 -tls=true
- 1
若想后台運行,則執行
nohup ./collidermain -port=8089 -tls=true &
- 1
5. 搭建STUN\TURN服務器
- 安裝coturn
apt-get install coturn
- 1
- 進行相關配置
- 編輯文件/etc/default/coturn,把TURNSERVER_ENABLED=1的注釋去掉。
- 編輯文件/etc/turnserver.conf,把以下內容加入到文件最后(或者在文件中找到相應的選項,進行配置)
listening-device=eth0 #此處eth0是電腦網卡名稱
listening-port=3478 #turn服務器的端口號
relay-device=eth0 #此處eth0是電腦網卡名稱
min-port=49152
max-port=65535
Verbose
fingerprint
lt-cred-mech
use-auth-secret
static-auth-secret=inesadt #此處要和房間服務器配置時constants.py文件中的CODE_KEY保持一致。
user=inesadt:0x7e3a2ed35d3cf7f19e2f8b015a186f54
user=inesadt:inesadt
stale-nonce
cert=/usr/local/etc/turn_server_cert.pem
pkey=/usr/local/etc/turn_server_pkey.pem
no-loopback-peers
no-multicast-peers
mobility
no-cli
上述文件中 0x7e3a2ed35d3cf7f19e2f8b015a186f54的生成方法: turnadmin -k -u inesadt -r north.gov -p inesadt
-k 表示生成一個long-term credential key
-u 表示用戶名
-p 表示密碼
-r 表示Realm域,(這個值的設置可能會有影響)。
coturn的證書生成(即配置文件中cert和pkey)
sudo openssl req -x509 -newkey rsa:2048 -keyout /usr/local/etc/turn_server_pkey.pem –out /usr/local/etc/turn_server_cert.pem -days 99999 –nodes
- 1
- 啟動coturn服務器
service coturn start
- 1
6. 配置Nginx服務器
- 安裝Nginx
apt-get install nginx
- 1
- 配置Nginx
編輯配置文件/etc/nginx/sites-available/default
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name webrtc.olcms.com; #添加域名,如不添加,生成SSL證書時可能會有問題
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
.....
....
}
-
生成SSL證書
1.使用let’s encrypt頒發的免費SSL證書,安裝軟件
sudo apt-get update
apt-get install software-properties-common
add-apt-repository ppa:certbot/certbot
apt-get update
apt-get install python-certbot-nginx
2.生成SSL證書
certbot --nginx certonly
- 1
SSL證書生成的目錄/etc/letsencrypt/live/webrtc.olcms.com/,下面會有四個證書(cert.pem,chain.pem,fullchain.pem,privkey.pem)
PS:詳見https://certbot.eff.org/#ubuntuxenial-nginx
- 安裝php和php-fpm
apt-get install php
apt-get install php7.0-fpm
- 1
- 2
- 編輯配置文件/etc/nginx/sites-available/default
upstream roomserver {
server 114.215.131.216:8080;
}
server {
listen 80 ;
server_name webrtc.olcms.com;
return 301 https://$server_name$request_uri;
}
server {
# listen 80 default_server;
# listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
listen 443;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html index.php; #此處添加index.php
server_name webrtc.olcms.com;
# location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
# }
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
include snippets/fastcgi-php.conf;
# With php7.0-cgi alone:
#fastcgi_pass 127.0.0.1:9000;
# With php7.0-fpm:
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location / {
proxy_pass http://roomserver$request_uri;
proxy_set_header Host $host;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
ssl on;
ssl_certificate /etc/letsencrypt/live/webrtc.olcms.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/webrtc.olcms.com/privkey.pem;
}
- 編寫turn.php文件和iceconfig.php文件,並把文件放到目錄/var/www/html/目錄下
turn.php文件內容
<?php $request_username = $_GET["username"]; if(empty($request_username)) { echo "username == null"; exit; } $request_key = $_GET["key"]; $time_to_live = 600; $timestamp = time() + $time_to_live;//失效時間 $response_username = $timestamp.":".$_GET["username"]; $response_key = $request_key; if(empty($response_key)) $response_key = "code_key"; //constants.py中CEOD_KEY $response_password = getSignature($response_username, $response_key); $jsonObj = new Response(); $jsonObj->username = $response_username; $jsonObj->password = $response_password; $jsonObj->ttl = 86400; //此處需配置自己的服務器 $jsonObj->uris= array("stun:webrtc.olcms.com:3478","turn:webrtc.olcms.com:3478?transport=udp","turn:webrtc.olcms.com?transport=tcp"); echo json_encode($jsonObj); /** * 使用HMAC-SHA1算法生成簽名值 * * @param $str 源串 * @param $key 密鑰 * * @return 簽名值 */ function getSignature($str, $key) { $signature = ""; if (function_exists('hash_hmac')) { $signature = base64_encode(hash_hmac("sha1", $str, $key, true)); } else { $blocksize = 64; $hashfunc = 'sha1'; if (strlen($key) > $blocksize) { $key = pack('H*', $hashfunc($key)); } $key = str_pad($key, $blocksize, chr(0x00)); $ipad = str_repeat(chr(0x36), $blocksize); $opad = str_repeat(chr(0x5c), $blocksize); $hmac = pack( 'H*', $hashfunc( ($key ^ $opad) . pack( 'H*', $hashfunc( ($key ^ $ipad) . $str ) ) ) ); $signature = base64_encode($hmac); } return $signature; } class Response { public $username = ""; public $password = ""; public $ttl = ""; public $uris = array(""); } ?>
iceconfig.php文件內容
<?php $request_username = "inesadt"; //配置成自己的turn服務器用戶名 if(empty($request_username)) { echo "username == null"; exit; } $request_key = "inesadt"; //配置成自己的turn服務器密碼 $time_to_live = 600; $timestamp = time() + $time_to_live;//失效時間 $response_username = $timestamp.":".$_GET["username"]; $response_key = $request_key; if(empty($response_key)) $response_key = "CEOD_KEY";//constants.py中CEOD_KEY $response_password = getSignature($response_username, $response_key); $arrayObj = array(); $arrayObj[0]['username'] = $response_username; $arrayObj[0]['credential'] = $response_password; //配置成自己的stun/turn服務器 $arrayObj[0]['urls'][0] = "stun:webrtc.olcms.com:3478"; $arrayObj[0]['urls'][1] = "turn:webrtc.olcms.com:3478?transport=tcp"; $arrayObj[0]['uris'][0] = "stun:webrtc.olcms.com:3478"; $arrayObj[0]['uris'][1] = "turn:webrtc.olcms.com:3478?transport=tcp"; $jsonObj = new Response(); $jsonObj->lifetimeDuration = "300.000s"; $jsonObj->iceServers = $arrayObj; echo json_encode($jsonObj); /** * 使用HMAC-SHA1算法生成簽名值 * * @param $str 源串 * @param $key 密鑰 * * @return 簽名值 */ function getSignature($str, $key) { $signature = ""; if (function_exists('hash_hmac')) { $signature = base64_encode(hash_hmac("sha1", $str, $key, true)); } else { $blocksize = 64; hashfunc = 'sha1'; if (strlen($key) > $blocksize) { $key = pack('H*', $hashfunc($key)); } $key = str_pad($key, $blocksize, chr(0x00)); $ipad = str_repeat(chr(0x36), $blocksize); $opad = str_repeat(chr(0x5c), $blocksize); $hmac = pack( 'H*', $hashfunc( ($key ^ $opad) . pack( 'H*', $hashfunc( ($key ^ $ipad) . $str ) ) ) ); $signature = base64_encode($hmac); } return $signature; } class Response { public $lifetimeDuration = ""; public $iceServers = array(""); } ?>
- 重啟Nginx服務器和php7.0-fpm
service nginx restart
service php7.0-fpm restart
- 1
- 2
7. 運行測試
-
PC瀏覽器(Android手機瀏覽器)之間的視頻通信測試
訪問 https://webrtc.olcms.com
1.PC瀏覽器:Firefox 54.0.1(64bits),Android手機瀏覽器:Firefox 54.0.1測試OK
2.PC瀏覽器:Google Chrome 59.0.3071.115(64bits),Android手機瀏覽器:Google Chrome 59.0.3071.125
測試OK
-
Android APK客戶端之間以及客戶端與瀏覽器之間
1.獲取Android APK下載webrtc源碼,在源碼目錄下webrtc/examples/androidapp,進行編譯即可生成Android APK
2.測試Android APK客戶端之間
測試OK
3.測試Android APK客戶端與瀏覽器(Chrome、Firefox)之間
測試OK
附錄
- 運行過程中的問題
-
- Failed to start signaling: Failed to execute ‘pushState’ on ‘History’: A history state object with URL ‘http://192.168.6.54/r/198676628’ cannot be created in a document with origin ‘https://192.168.6.54’ and URL ‘https://192.168.6.54/
解決方法1:
房間服務器編譯完成后,在/root/apprtc/out/app_engine/js/apprtc.debug.js文件中找到window.history.pushState({‘roomId’: roomId, ‘roomLink’: roomLink}, roomId, roomLink),把這句話注釋掉,重新運行即可。(如果重新編譯,需要重新修改)解決方法2:
在/root/apprtc/src/web_app/js/appcontroller.js文件中找到window.history.pushState({‘roomId’: roomId, ‘roomLink’: roomLink}, roomId, roomLink),把這句話注釋掉,然后重新編譯,重新運行房間服務器即可。
回到目錄
參考:
1.http://io.diveinedu.com/2015/02/05/%E7%AC%AC%E5%85%AD%E7%AB%A0-WebRTC%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA.html
2. http://www.jianshu.com/p/3a43233b9c39