zoukankan      html  css  js  c++  java
  • WebRTC

    Webrtc服务器搭建(基于局域网环境)

    • 目录
    1. 搭建平台
    2. 软件安装
    3. 搭建房间服务器(Room Server)
    4. 搭建信令服务器(Collider Server)
    5. 搭建STUNTURN服务器
    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 &
    
    • 搭建STUNTURN服务器
    • 安装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
    
  • 相关阅读:
    PHP命名空间
    php各个版本的区别
    MySQL的读写分离---主从复制、主主复制
    redis的安装和php的redis扩展
    php的设计模式
    git命令详情
    memcache和redis的对比
    mysql性能优化
    MySQL的分区、分表、集群
    nginx的反向代理和负载均衡
  • 原文地址:https://www.cnblogs.com/evescn/p/10692378.html
Copyright © 2011-2022 走看看