Webrtc服務器搭建(基於局域網環境)
- 目錄
1. 搭建平台
2. 軟件安裝
3. 搭建房間服務器(Room Server)
4. 搭建信令服務器(Collider Server)
5. 搭建STUN\TURN服務器
6. 配置Nginx服務器
7. 運行測試
8. 參考文檔
- 搭建平台
操作系統:Ubuntu 16.04 server(64bits)
Google webrtc的服務器Demo:詳見 https://github.com/webrtc/apprtc
IP地址:局域網 10.120.10.142
- 軟件安裝
- 安裝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
- 搭建房間服務器(Room Server)
- 下載apprtc源碼(操作所在目錄/root/)
# git clone https://github.com/webrtc/apprtc.git
# cd apprtc
## 安裝軟件依賴
# npm install
- 修改文件
# vim /root/apprtc/src/app_engine/constants.py
TURN_BASE_URL = 'http://10.120.10.142:80'; #本機內網地址10.120.10.142,此處的端口號與Nginx監聽的端口號保持一致
TURN_URL_TEMPLATE = '%s/turn.php?username=%s&key=%s'; #如果turn.php未實現,可使用默認配置
CEOD_KEY = 'inesadt' #此處后面turn配置的用戶名保持一致
ICE_SERVER_BASE_URL = 'http://10.120.10.142:80';#此處的端口號與Nginx監聽的端口號保持一致
ICE_SERVER_URL_TEMPLATE = '%s/iceconfig.php?key=%s'; #如果iceconfig.php未實現,可用默認配置,但是Android Apk會有問題
WSS_INSTANCE_HOST_KEY = '10.120.10.142:8089' #信令服務器端口號8089
WSS_INSTANCE_NAME_KEY = 'vm_name'
WSS_INSTANCE_ZONE_KEY = 'zone'
WSS_INSTANCES = [{
WSS_INSTANCE_HOST_KEY: '10.120.10.142:8089',
WSS_INSTANCE_NAME_KEY: 'wsserver-std',
WSS_INSTANCE_ZONE_KEY: 'us-central1-a'
}, {
WSS_INSTANCE_HOST_KEY: '10.120.10.142:8089',
WSS_INSTANCE_NAME_KEY: 'wsserver-std-2',
WSS_INSTANCE_ZONE_KEY: 'us-central1-f'
}]
# vim /root/apprtc/src/app_engine/apprtc.py (若使用https,則不需修改此文件)
if wss_tls and wss_tls == 'false':
wss_url = 'ws://' + wss_host_port_pair + '/ws'
wss_post_url = 'http://' + wss_host_port_pair
else:
wss_url = 'ws://' + wss_host_port_pair + '/ws'
wss_post_url = 'http://' + wss_host_port_pair
- 編譯(在apprtc目錄下進行)
# grunt build
編譯完成之后,會生成out目錄,房間服務器編譯完成。
編譯失敗請參考文檔:https://blog.csdn.net/gladsnow/article/details/77900333
- 安裝和配置google app engine
1、下載google app engine
需翻牆,下載地址:https://storage.googleapis.com/appengine-sdks/featured/google_appengine_1.9.50.zip,或者通過其他地方下載。
2、配置google app engine 路徑
# unzip google_appengine_1.9.50.zip
## 編輯/etc/profile文件,在文件最后添加語句:
export PATH="$PATH:/root/google_appengine/"
# source /etc/profile
- 運行房間服務器(room server)
# cd /root/google_appengine
# ./dev_appserver.py --host=10.120.10.142 /root/apprtc/out/app_engine
## 后台運行
# nohup ./dev_appserver.py --host=192.168.6.54 /root/apprtc/out/app_engine &
- 在瀏覽器中訪問房間服務器
http://10.120.10.142:8080
- 搭建信令服務器(Collider Server)
- 安裝go語言編譯器
# apt-get install golang-go
- 復制collider源代碼
## 此源碼在房間服務器源碼目錄下/root/apprtc/src/collider/
# cd /root
# mkdir -p goWorkspace/src
## 配置編譯環境,此配置是暫時有效的
# export GOPATH=/root/goWorkspace/
## 把/root/apprtc/src/collider/目錄下的三個目錄(collider、collidermain、collidertest)復制到/root/goWorkspace/src/目錄下
# cp -rf /root/apprtc/src/collider/* /root/goWorkspace/src
- 修改代碼
編輯文件/root/goWorkspace/src/collidermain/main.go,修改房間服務器的地址
var roomSrv = flag.String("room-server", "http://10.120.10.142:8080", "The origin of the room server")
- 編譯信令服務器
## 進入目錄/root/goWorkspace/src/,此處編譯需要翻牆。可手動下載需要的文件。在/root/goWorkspace/src/目錄下
# mkdir -p golang.org/x
# cd golang.org/x/
# git clone https://github.com/golang/net
## 然后再進行編譯即可
# cd /root/goWorkspace/src/
# go get collidermain
# go install collidermain
- 運行信令服務器
# cd /root/goWorkspace/bin/
# ./collidermain -port=8089 -tls=false
## 若想后台運行,則執行
# nohup ./collidermain -port=8089 -tls=false &
- 搭建STUN\TURN服務器
- 安裝coturn
# apt-get install coturn
- 修改配置
編輯文件/etc/default/coturn,把TURNSERVER_ENABLED=1的注釋去掉。
# vim /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
- 啟動coturn服務器
# service coturn start
- 配置Nginx服務器
- 安裝Nginx
# apt-get install nginx
- 安裝php和php-fpm
# apt-get install php
# apt-get install php7.0-fpm
- 編輯配置文件/etc/nginx/sites-available/default
upstream roomserver {
server 192.168.6.54:8080;
}
server {
#listen 80 default_server;
#listen [::]:80 default_server;
listen 80;
# 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 index.php; #此處添加index.php
server_name _;
# 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;
#}
}
- 編寫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:10.120.10.142:3478","turn:10.120.10.142:3478?transport=udp","turn:10.120.10.142:3478?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 = "0x7e3a2ed35d3cf7f19e2f8b015a186f54"; //配置成自己的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:10.120.10.142:3478";
$arrayObj[0]['urls'][1] = "turn:10.120.10.142:3478?transport=tcp";
$arrayObj[0]['uris'][0] = "stun:10.120.10.142:3478";
$arrayObj[0]['uris'][1] = "turn:10.120.10.142: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("");
}
?>
注:關於turn.php和iceconfig.php文件實現的必要性,如果是http局域網,即使不實現這兩個文件,在瀏覽器之間也可實現視頻通信,但是如果使用Google的Android apk作為客戶端,則可能會存在問題。經過測試,實現iceconfig.php即可,turn.php文件可不實現。
- 重啟Nginx服務器和php7.0-fpm
# service nginx restart
# service php7.0-fpm restart
- 運行測試
- PC瀏覽器(Android手機瀏覽器)之間的視頻通信測試
訪問http://192.168.6.54:8080
1.PC瀏覽器:Firefox,Android手機瀏覽器:Firefox
測試OK
- 參考文檔
- 基於內網環境WebRTC搭建文檔
https://blog.csdn.net/gladsnow/article/details/77900333 - 基於公網環境WebRTC搭建文檔
https://blog.csdn.net/gladsnow/article/details/77900578
