# WebRTC
網頁即時通信(Web Real-Time Communication),是一個支持[網頁瀏覽器](https://baike.baidu.com/item/%E7%BD%91%E9%A1%B5%E6%B5%8F%E8%A7%88%E5%99%A8)進行實時語音對話或視頻對話的API。
**房間服務器**
開源實現: https://github.com/webrtc/apprtc
房間服務器是用來創建和管理通話會話的狀態維護,是通話還是多方通話,加入與離開房間等等
**信令服務器**
apprtc中。
信令就是協調通訊的過程,為了建立一個webRTC的通訊過程,客戶端需要交換如下信息
```
1. 會話控制信息,用來開始和結束通話,即開始視頻、結束視頻這些操作指令。
2. 發生錯誤時用來相互通告的消息
3. 元數據,如各自的音視頻解碼方式、帶寬。
4. 網絡數據,對方的公網IP、端口、內網IP及端口。
```
**內網穿透服務器**
https://github.com/coturn/coturn/wiki/Downloads
元數據是通過信令服務器中轉發給另一個客戶端,但是對於流媒體數據,一旦會話建立,首先嘗試使用點對點連接。每個客戶端都有一個唯一的地址,他能用來和其他客戶端進行通訊和數據交換。
一般情況下,連接互聯網時都處於防火牆后面或者配置私有子網的家庭路由器后面,導致我們的計算機的IP地址不是廣域網IP地址,故而不能相互之間直接通訊。讓兩個同處於私有網絡里的計算機能夠通訊起來,這種技術通常稱為NAT穿透。WebRTC 可以使用ICE框架去克服真實世界的復雜網絡。
STUN (Simple Traversal of UDP Through NAT),是一個完整的NAT穿透解決方案,即簡單的用UDP穿透NAT。
TURN (Traversal Using Relay NAT), 與STUN一樣為了完成穿透效果,但是TURN是通過轉發的方式來實現穿透。
ICE (Interactive Connectivity Establishment), 綜合以上2種協議的綜合性NAT穿越解決方案。首先會嘗試用設備系統或網卡獲取到的主機地址去建立連接;如果這個失敗了(設備在NATs后面就會)ICE從STUN服務器獲得外部的地址,如果這個也失敗了,就用TURN中轉服務器做通訊。
服務器:Ubuntu 16.04 版本
---
XShell
sudo apt-get install openssh-server
----
> 在阿里雲后台開放端口(入隊規則)端口: 3478、8080、8089、80、443
目錄於: `/root/webrtc`
> Linux 后台運行的命令用:前面加 nohup 后面加 &
注釋:locate dev_appserver.py 查看dev_appserver.py的本地路徑
## 搭建AppRTC
安裝需要的各種工具(除了apt之外還可以下載安裝包或者源碼自己編譯安裝):
1、安裝JDK
```shell
#為了演示初始環境 已重裝系統, 重裝后先執行:
apt-get update
apt-get install openjdk-8-jdk
java -version
#java version "1.8.0_181"
#Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
#Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
```
2、安裝node.js
```shell
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs
node --version
#v8.15.0
npm --version
#6.4.1
npm -g install grunt-cli
grunt --version
#grunt-cli v1.3.2
```
node --version 6.x 版本過低,目標升級到8.0
npm install -g n 安裝n模塊
n 8.15.0 升級到了8.0.0
node --version 成功升級到8.0
3、安裝Python和Python-webtest (python2.7)
```shell
apt-get install python
apt-get install python-webtest
python -V
#Python 2.7.12
```
4、安裝google_appengine
```shell 當前目錄:root/webrtc/
wget https://storage.googleapis.com/appengine-sdks/featured/google_appengine_1.9.40.zip
unzip google_appengine_1.9.40.zip
#配置環境變量:在/etc/profile文件最后增加一行:
export PATH=$PATH:/root/webrtc/google_appengine
source /etc/profile
```
5、安裝go
```shell
apt install golang-go
go version
#go version go1.6.2 linux/amd64
```
```shell
#創建go工作目錄
mkdir -p /root/webrtc/goWorkspace/src
#配置環境變量:在/etc/profile文件最后增加一行:
export GOPATH=/root/webrtc/goWorkspace
source /etc/profile
```
6、安裝libevent
```shell
#當前目錄:root/webrtc/
#https://github.com/coturn/coturn/wiki/CoturnConfig
wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
tar xvf libevent-2.0.21-stable.tar.gz
cd libevent-2.0.21-stable
./configure
make install
```
7、安裝apprtc(2018/11/10)
```shell
#當前目錄:root/webrtc/
git clone https://github.com/webrtc/apprtc.git
#將collider的源碼軟連接到go的工作目錄下
ln -s /root/webrtc/apprtc/src/collider/collider $GOPATH/src
ln -s /root/webrtc/apprtc/src/collider/collidermain $GOPATH/src
ln -s /root/webrtc/apprtc/src/collider/collidertest $GOPATH/src
#編譯collidermain
go get collidermain
go install collidermain
#go get collidermain: 被牆
#報錯: package golang.org/x/net/websocket: unrecognized import path "golang.org/x/net/websocket"
#執行:
#mkdir -p $GOPATH/src/golang.org/x/
#cd $GOPATH/src/golang.org/x/
#git clone https://github.com/golang/net.git net
#go install net
```
8、安裝coturn
```shell
#目錄:root/webrtc/
#https://github.com/coturn/coturn/wiki/Downloads
wget http://coturn.net/turnserver/v4.5.0.7/turnserver-4.5.0.7.tar.gz
tar xvfz turnserver-4.5.0.7.tar.gz
cd turnserver-4.5.0.7
./configure
make install
```
配置與運行:
1、coturn Nat穿透服務器
配置防火牆,允許訪問3478端口(含tcp和udp,此端口用於nat穿透)
```shell
#啟動 172.31.247.136:內網ip(阿里雲后台可以看到內外網ip)
nohup turnserver -L 172.31.247.136 -a -u dongnao:12345 -v -f -r nort.gov &
#賬號dongnao 密碼:12345 這一步隨便給,但是后面配置apprtc時需要用到
#命令后加 & ,執行起來后按 ctr+c,不會停止
```
```shell
#開啟新窗口 執行
netstat -ntulp | grep turnserver #或者 lsof -i:3478
#輸出大致這樣的成功
tcp 0 0 127.0.0.1:5766 0.0.0.0:* LISTEN 16848/turnserver
tcp 0 0 172.31.247.136:3478 0.0.0.0:* LISTEN 16848/turnserver
tcp 0 0 172.31.247.136:3478 0.0.0.0:* LISTEN 16848/turnserver
udp 0 0 172.31.247.136:3478 0.0.0.0:* 16848/turnserver
udp 0 0 172.31.247.136:3478 0.0.0.0:* 16848/turnserver
```
2、collider 信令服務器
配置防火牆,允許訪問8089端口(tcp,用於客戶端和collider建立websocket信令通信)
```shell
#創建自簽名的數字證書
#如果沒有openssl,需要安裝
mkdir -p /cert
cd /cert
# CA私鑰
openssl genrsa -out key.pem 2048
# 自簽名證書
openssl req -new -x509 -key key.pem -out cert.pem -days 1095
nohup $GOPATH/bin/collidermain -port=8089 -tls=true -room-server="https://47.75.90.219:8089" &
```
```shell
#同樣檢查是否成功
netstat -ntulp | grep collider
tcp6 0 0 :::8089 :::* LISTEN 16864/collidermain
```
3、apprtc 房間服務器
配置防火牆,允許訪問8080端口(tcp,此端口用於web訪問)
配置文件修改(主要是配置apprtc對應的conturn和collider相關參數)
```shell
vim /root/webrtc/apprtc/src/app_engine/constants.py
#47.75.90.219 外網ip
```

```shell
#編譯
cd /root/webrtc/apprtc
npm install
grunt build
> ** npm install錯誤
>npm ERR! code ELIFECYCLE
>npm ERR! errno 7
>npm ERR! closurecompiler@1.6.1 install: `npm run-script configure`
>npm ERR! Exit status 7**
>解決方式:
sudo npm install closurecompiler@1.6.1
#
```
> **錯誤: requests模塊不存在**
>
> ```shell
> ImportError: No module named requests
> Warning: Command failed: python ./build/build_app_engine_package.py src out/app_engine
> Traceback (most recent call last):
> File "./build/build_app_engine_package.py", line 12, in <module>
> import requests
> ImportError: No module named requests
> Use --force to continue.
>
> Aborted due to warnings.
> ```
>
> ##### 安裝pip
>
> 下載setup-python工具
>
> ```shell
> # 有一行命令太長了,$開頭的是一行命令
> $
> $wget https://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg --no-check-certificate
> $chmod +x setuptools-0.6c11-py2.7.egg
> $./setuptools-0.6c11-py2.7.egg
> $wget https://pypi.python.org/packages/source/p/pip/pip-1.5.4.tar.gz
> $tar -xf pip-1.5.4.tar.gz
> $cd pip-1.5.4
> $python setup.py install
> $cd ..
> $pip install requests
> #安裝完成后再執行編譯:
> #cd /root/webrtc/apprtc
> #grunt build
> ```
啟動:
```shell
#172.31.247.136 : 內網ip
nohup dev_appserver.py --host=192.168.25.102 /root/webrtc/apprtc/out/app_engine --skip_sdk_update_check &
#提示更新選擇:
```
```shell
#檢查
netstat -ntulp | grep 8080
#輸出下列內容
tcp 0 0 172.31.4.236:8080 0.0.0.0:* LISTEN 17032/python
```
4、nginx
反向代理apprtc,使之支持https訪問,如果http直接訪問apprtc,則客戶端無法啟動視頻音頻采集(必須得用https訪問)
```shell
wget http://nginx.org/download/nginx-1.15.6.tar.gz
tar xvf nginx-1.15.6.tar.gz
cd nginx-1.15.6
#在nginx目錄執行 PCRE:apt-get install libpcre3-dev
./configure --with-http_ssl_module
make install
#默認安裝在/usr/local/nginx(也可以執行prefix)
#配置nginx.conf
vim /usr/local/nginx/conf/nginx.conf
#內容如下(注意修改自己的公網ip)
```
```nginx
events {
worker_connections 1024;
}
http{
upstream roomserver {
server 192.168.25.102:8080;
}
server {
listen 80;
server_name 192.168.25.102;
return 301 https://$server_name$request_uri;
}
server {
root /usr/share/nginx/html;
index index.php index.html index.htm;
listen
ssl_certificate /cert/cert.pem;
ssl_certificate_key /cert/key.pem;
server_name 192.168.25.102;
location / {
proxy_pass http://roomserver$request_uri;
proxy_set_header Host $host;
}
location ~ .php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
}
```
> 啟動:
>
> /usr/local/nginx/sbin/nginx
> 瀏覽器通話跨域問題 :pushState
>
> Messages:Failed to start signaling: Failed to execute 'pushState' on 'History'
>
> ```shell
> vim /root/webrtc/apprtc/out/app_engine/js/apprtc.debug.js
> #搜索 pushState 增加:
> roomLink=roomLink.substring("http","https");
> ```
>
> 