WebRTC

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
		需FQ,下载地址: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/,此处编译需要FQ。可手动下载需要的文件。在/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
posted @ 2019-04-11 20:43  evescn  阅读(743)  评论(0编辑  收藏  举报