搭建AppRTC服務器 (AppRTC+Collider+Coturn) 2019

本文介紹使用域名 HTTPS 的方式部署AppRTC服務,信令服務和STURN/TURN服務。
本文使用虛擬機橋接模式下的Ubuntu18.04系統和小飛機代理。
因爲項目需要本地搭建一個AppRTC服務器,研究了好幾天才基本弄完,但是也只是Web端可以訪問,好多坑( ⊙ o ⊙ ),記錄一下。

0 準備工作

0.1 配置代理

服務器使用Ubuntu,服務器端需要用代理的時候,使用Shadowsocks + Proxychains代理方式。

0.1.1 SS

安裝SS

sudo apt-get install shadowsocks

配置文件ss.json,使用1080本地端口

{
    "server":"sample.com", 	# 代理服務器
    "server_port":1234,		# 端口
    "local_address":"0.0.0.0",
    "local_port":1080,
    "password":"password",	# 遠程服務密碼
    "timeout":300,
    "method":"aes-256-cfb"
}

啓動SS

sudo sslocal -c ./ss-liming.json -d start

0.1.2 Proxychains4

Ubuntu可以直接安裝Proxychains4 或 Proxychains。

sudo apt-get install proxychains4

配置文件/etc/proxychains4.conf添加

socks5 127.0.0.1 1080

使用方式
任何需要代理的命令,可以在命令前面添加proxychains4,比如

proxychains4 curl xxxx
proxychains4 wget xxxx
sudo proxychains4 apt-get install xxxx
或者
proxychains bash

0.1.3 npm代理方式*

這個等需要代理的時候再設置。
設置代理

npm config set proxy=http://127.0.0.1:1080
npm config set https-proxy http://127.0.0.1:1080

刪除代理

npm config delete proxy
npm config delete https-proxy

0.2 Google App Engine SDK,以及創建gcloud工程

GAE SDK是AppRTC部署工具,有好幾個版本,我選用的是Node.js版本,不着急安,往下看。

0.2.1 Node.js & npm

可以安裝Ubuntu倉庫的版本,也可以使用官網介紹安裝最新版本。

sudo apt-get install nodejs npm

0.2.2 Java

安裝OpenJDK

sudo apt-get install openjdk-8-jdk

0.2.2 Google Cloud SDK

項目地址 https://cloud.google.com/sdk/docs/#linux ,Linux可以下載通用的二進制包,配置環境變量。方便起見,Ubuntu可以使用在線下載的方式

Ubuntu在線安裝GCloud SDK,注意:需要代理的命令前加proxychains4。

## 添加源
export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)"
echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

## 安裝
sudo apt-get update
sudo apt-get install google-cloud-sdk
sudo apt-get install google-cloud-sdk-app-engine-python
sudo apt-get install google-cloud-sdk-datastore-emulator
sudo apt-get install google-cloud-sdk-app-engine-python-extras
0.2.3 初始化Google Cloud
gcloud init
# proxychains4 gcloud init

提示登錄Google賬號,按Y確認,出現登錄鏈接,把這個鏈接粘到瀏覽器,登陸後返回驗證字符串,再粘到下面的。

如果電腦安裝了瀏覽器會自動打開瀏覽器進行登錄驗證,若瀏覽器出現跳轉錯誤,那就把瀏覽器先卸了。
如果還是出錯,先執行proxychains gcloud auth login --no-launch-browser認證,然後再gcloud init

Go to the following link in your browser:
    https://accounts.google.com/o/oauth2/auth?...
Enter verification code: 

提示使用已存在的GCloud工程或者創建新工程。

Pick cloud project to use: 
 [1] apprtc-237109
 [2] Create a new project

可以選創建新工程直接輸入小寫字母的工程名字,但是可能會創建失敗。
如果創建失敗,則可以在瀏覽器中自己創建工程,然後直接選已存在的工程即可。GCloud工程管理鏈接:
https://console.cloud.google.com/cloud-resource-manager

0.3 域名與證書

HTTPS 方式部署 AppRTC 需要證書,如果有域名的話可以申請 CA 證書,參考另一篇文章《快速申請 Let’s Encrypt 免費SSL證書 / CA證書》。
如果使用的服務器沒有公網 IP,可以配置服務器和本機hosts文件,使其域名都指向該服務器IP。如果有公網 IP 應設置域名A記錄指向服務器IP。

進入正題~
AppRTC是會議服務,Collider是信令服務,Coturn是中繼服務。可以一個一個部署。

1. AppRTC

這一步先測試AppRTC服務,使用Google默認的信令和TURN服務。

1.1 下載源碼

git clone https://github.com/webrtc/apprtc.git

1.2 安裝node.js依賴

npm install
npm install grunt # 編譯工具

如果出現連接問題的話要設置npm代理

npm config set proxy=http://127.0.0.1:1080
npm config set https-proxy http://127.0.0.1:1080

如果有其他錯誤,可以按照提示執行npm audit fix修復,可能會反覆執行幾遍npm installnpm audit fix

1.3 安裝node.js依賴

sudo apt install python-pip
pip install -r requirements.txt

如果需要代理可以試試

proxychains pip install -r requirements.txt

1.4 安裝JDK

前面沒安裝JDK的話,需要安裝JDK。可以自行下載 Oracle JDK 安裝,配置環境變量。方便起見可以在線安裝OpenJDK。

apt-get install openjdk-8-jdk

1.5 編譯

保證這步沒有錯誤

# sudo npm install grunt -g # 先安裝grunt
grunt build

1.6 部署運行

這一步介紹使用默認信令和TURN服務部署AppRTC,僅作測試使用,完全部署必須配置信令服務和TURN服務。
建議配置其他服務之前先保證此測試服務正常。

1.6.1 HTTP 方式

<path to gclud sdk>/dev_appserver.py --host <server-ip> ./out/app_engine

注意:
離線安裝GCloud,dev_appserver.py 文件位於google-cloud-sdk/bin/目錄下,
在線安裝的方式,位於/usr/lib/google-cloud-sdk/bin/目錄下。若該目錄已經添加到PATH,則可以直接執行dev_appserver.py

1.6.2 HTTPS 方式

需要證書,我使用的是域名apprtc.lmshao.com和相應的證書,不知道使用IP和自簽名證書是否可行。因爲使用的虛擬機沒有公網IP,我把服務器的hosts的域名指到了服務器的IP了。
命令行指定域名和證書路徑,和生成程序的路徑./apprtc/out/app_engine

dev_appserver.py --host apprtc.lmshao.com ./apprtc/out/app_engine --ssl_certificate_path /cert/cert.pem --ssl_certificate_key_path /cert/key.pem --skip_sdk_update_check

我這裏會提示默認服務地址:

我在我的Windows電腦上也設置了hosts,Chrome不支持WebRTC通過http方式鏈接,使用Chrome可以打開這個https的鏈接了。
注意:因爲這裏只配置了AppRTC 服務,其他使用的是Google默認服務,所以客戶端需要打開小飛機代理,又因爲虛擬機配置了hosts,所以應該使用小飛機的PAC模式。
到目前爲止打開瀏覽器應該可以正常使用了,只是參會人數默認有2人限制。如果這一步出錯,就不要進行下面的了,先把這步走通再繼續。

1.6.3 常見問題

問題 1
Chrome瀏覽器不支持 HTTP 方式使用 WebRTC 服務器,會導致沒法獲取攝像頭數據,Firefox有可能會支持。最好的方式是使用HTTPS方式部署
沒有域名的話可以配置服務器和本機的hosts文件,把特定域名指向服務器的IP地址。

問題2
至此使用的是默認的Google 信令和TURN服務,客戶端訪問需要開PAC代理,否則沒法正常視頻會議。

2. Collider 信令服務

2.1 安裝Golang

sudo apt-get install golang

2.2 配置Go工作區

創建快捷方式

export GOPATH=$HOME/goWorkspace/
mkdir $GOPATH/src
ln -s `pwd`/apprtc/src/collider/collider $GOPATH/src
ln -s `pwd`/apprtc/src/collider/collidermain $GOPATH/src
ln -s `pwd`/apprtc/src/collider/collidertest $GOPATH/src

2.3 安裝collidermain

安裝依賴

go get collidermain
# proxychains go get collidermain

每次重新編譯apprtc,都要安裝一次

go install collidermain

2.4 運行 Collider 服務

命令行指定參數,通常使用的就是8089端口,tls使用加密方式secure websocket,這裏指的是apprtc服務與collider之間的連接,room-server指的是AppRTC的服務地址,使用https方式的8081端口。

需要把證書和祕鑰文件放在/cert目錄下,即/cert/cert.pem /cert/key.pem

goWorkspace/bin/collidermain -port=8089 -tls=true -room-server="https://apprtc.lmshao.com:8081"

如果命令行未指定參數,則從文件中讀取。所以也可以通過修改配置文件指定參數apprtc/src/collider/collidermain/main.go

var tls = flag.Bool("tls", true, "whether TLS is used")
var port = flag.Int("port", 8089, "The TCP port that the server listens on")
var roomSrv = flag.String("room-server", "https://263.net:8081", "The origin of the room server")

注意:
修改文件後,要重新編譯apprtc、安裝collidermain

cd apprtc
grunt build
go install collidermain

2.5 配置AppRTC 使用 Collider

修改apprtc/src/app_engine/constants.py,把WSS_INSTANCE_HOST_KEYhost_port_pair改爲 Collider的地址apprtc.lmshao.com:8089

#WSS_INSTANCE_HOST_KEY = 'host_port_pair'
WSS_INSTANCE_HOST_KEY = '263.net:8089'
WSS_INSTANCE_NAME_KEY = 'vm_name'
WSS_INSTANCE_ZONE_KEY = 'zone'
WSS_INSTANCES = [{
    WSS_INSTANCE_HOST_KEY: '263.net:8089',
    WSS_INSTANCE_NAME_KEY: 'wsserver-std',
    WSS_INSTANCE_ZONE_KEY: 'us-central1-a'
}, {
    WSS_INSTANCE_HOST_KEY: '263.net:8089',
    WSS_INSTANCE_NAME_KEY: 'wsserver-std-2',
    WSS_INSTANCE_ZONE_KEY: 'us-central1-f'
}]

WSS_INSTANCES數組兩個信令服務器可以刪除一個

重新編譯AppRTC

cd apprtc
grunt build
go install collidermain

先運行Collider

goWorkspace/bin/collidermain -port=8089 -tls=true -room-server="https://apprtc.lmshao.com:8081"
dev_appserver.py --host apprtc.lmshao.com ./apprtc/out/app_engine --ssl_certificate_path /cert/cert.pem --ssl_certificate_key_path /cert/key.pem --skip_sdk_update_check

如果不加Collider之前AppRTC可以正常工作,那麼這時應該也可以參會。若不能參會,打開小飛機PAC代理試試。

3. Coturn TURN服務

3.1 在線安裝

Ubuntu可以在線安裝,能自動安裝其他依賴項libevent等多個庫。

sudo apt-get install coturn

3.1 離線安裝*

安裝libevent

$ wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
$ tar xvfz libevent-2.0.21-stable.tar.gz
$ cd libevent-2.0.21-stable
$ ./configure
$ make
$ sudo make install

安裝SQLite3

安裝CoTurn

$ wget https://coturn.net/turnserver/v4.5.0.8/turnserver-4.5.0.8.tar.gz
$ tar xvfz turnserver*.tar.gz
$ ./configure
$ make
$ sudo make install

3.3 配置

創建用戶

$ sudo turnadmin -a -u 用戶名 -p 密碼 -r 域(寫你自己服務器的IP/域名)
$ sudo turnadmin -a -u liming -p 12345678 -r apprtc.lmshao.com

可以查看用戶

$ turnadmin -l
liming[apprtc.lmshao.com]

3.4 啓動CoTurn服務

參數可以直接命令行指定,也可以用配置文件,默認參數會使用配置文件/etc/turnserver.conf的參數。

sudo turnserver -v -L 192.168.198.135 -a -f -r apprtc.lmshao.com -u liming:12345678 --cer /cert/cert.pem --pkey /cert/key.pem

詳細參數說明

參數 說明
-v 日誌輸出級別
-L 綁定網卡IP
-a 使用長期憑證機制,turn中繼轉發模式,必須使用長期憑證機制
-f 指定 turn 消息使用 fingerprint
-r 指定域名
-u 用戶名密碼 -u user:password
–cert 證書路徑
–pkey 祕鑰路徑
-c 指定配置文件,否則使用默認配置文件/etc/turnserver.conf

最簡單的啓動參數

# 前臺進程
$ turnserver -L <public_ip_address> -a -f -r <realm-name>
# 後臺服務
$ turnserver -L <public_ip_address> -o -a -f -r <realm-name>

測試CoTurn服務

turnutils_uclient apprtc.lmshao.com -u liming -w 12345678
turnutils_uclient 域名 -u 用戶名 -w 密碼

正常情況下運行不出錯的話,過一會會出現測試結果。

3.5 配置AppRTC啓動CoTurn

編輯 apprtc/src/app_engine/constants.py,重新編譯執行即可。

#ICE_SERVER_OVERRIDE = None

# Enable by uncomment below and comment out above, then specify turn and stun

ICE_SERVER_OVERRIDE  = [
  {
    "urls": [
      "turn:apprtc.lmshao.com:3478?transport=udp",
      "turn:apprtc.lmshao.com:3478?transport=tcp"
    ],
    "username": "liming",
    "credential": "12345678"
  },
  {
    "urls": [
      "stun:apprtc.lmshao.com:3478:3478"
    ]
  }
]

ICE_SERVER_BASE_URL = 'https://networktraversal.googleapis.com'
ICE_SERVER_URL_TEMPLATE = '%s/v1alpha/iceconfig?key=%s'
ICE_SERVER_API_KEY = os.environ.get('ICE_SERVER_API_KEY')

4. AppRTC & Collider & Coturn

4.1 AppRTC配置

至此,這個服務都配置好了,下面是完整的apprtc/src/app_engine/constants.py配置。

# Copyright 2015 Google Inc. All Rights Reserved.

"""AppRTC Constants.

This module contains the constants used in AppRTC Python modules.
"""
import os

# Deprecated domains which we should to redirect to REDIRECT_URL.
REDIRECT_DOMAINS =  [
  'apprtc.appspot.com', 'apprtc.webrtc.org', 'www.appr.tc'
]
# URL which we should redirect to if matching in REDIRECT_DOMAINS.
REDIRECT_URL = 'https://appr.tc'

ROOM_MEMCACHE_EXPIRATION_SEC = 60 * 60 * 24
MEMCACHE_RETRY_LIMIT = 100

LOOPBACK_CLIENT_ID = 'LOOPBACK_CLIENT_ID'

# Turn/Stun server override. This allows AppRTC to connect to turn servers
# directly rather than retrieving them from an ICE server provider.

# ICE_SERVER_OVERRIDE = None

# Enable by uncomment below and comment out above, then specify turn and stun

ICE_SERVER_OVERRIDE  = [
  {
    "urls": [
      "turn:apprtc.lmsaho.com:3478?transport=udp",
      "turn:apprtc.lmsaho.com:3478?transport=tcp"
    ],
    "username": "liming",
    "credential": "12345678"
  },
  {
    "urls": [
      "stun:apprtc.lmsaho.com:3478"
    ]
  }
]

ICE_SERVER_BASE_URL = 'https://networktraversal.googleapis.com'
ICE_SERVER_URL_TEMPLATE = '%s/v1alpha/iceconfig?key=%s'
ICE_SERVER_API_KEY = os.environ.get('ICE_SERVER_API_KEY')

# Dictionary keys in the collider instance info constant.

WSS_INSTANCE_HOST_KEY = 'apprtc.lmsaho.com:8089'
WSS_INSTANCE_NAME_KEY = 'vm_name'
WSS_INSTANCE_ZONE_KEY = 'zone'
WSS_INSTANCES = [{
    WSS_INSTANCE_HOST_KEY: 'apprtc.lmsaho.com:8089',
    WSS_INSTANCE_NAME_KEY: 'wsserver-std',
    WSS_INSTANCE_ZONE_KEY: 'us-central1-a'
}
#, {
#    WSS_INSTANCE_HOST_KEY: 'apprtc.lmsaho.com:8089',
#    WSS_INSTANCE_NAME_KEY: 'wsserver-std-2',
#    WSS_INSTANCE_ZONE_KEY: 'us-central1-f'
#}
]

WSS_HOST_PORT_PAIRS = [ins[WSS_INSTANCE_HOST_KEY] for ins in WSS_INSTANCES]

# memcache key for the active collider host.
WSS_HOST_ACTIVE_HOST_KEY = 'wss_host_active_host'

# Dictionary keys in the collider probing result.
WSS_HOST_IS_UP_KEY = 'is_up'
WSS_HOST_STATUS_CODE_KEY = 'status_code'
WSS_HOST_ERROR_MESSAGE_KEY = 'error_message'

RESPONSE_ERROR = 'ERROR'
RESPONSE_ROOM_FULL = 'FULL'
RESPONSE_UNKNOWN_ROOM = 'UNKNOWN_ROOM'
RESPONSE_UNKNOWN_CLIENT = 'UNKNOWN_CLIENT'
RESPONSE_DUPLICATE_CLIENT = 'DUPLICATE_CLIENT'
RESPONSE_SUCCESS = 'SUCCESS'
RESPONSE_INVALID_REQUEST = 'INVALID_REQUEST'

IS_DEV_SERVER = os.environ.get('APPLICATION_ID', '').startswith('dev')

BIGQUERY_URL = 'https://www.googleapis.com/auth/bigquery'

# Dataset used in production.
BIGQUERY_DATASET_PROD = 'prod'

# Dataset used when running locally.
BIGQUERY_DATASET_LOCAL = 'dev'

# BigQuery table within the dataset.
BIGQUERY_TABLE = 'analytics'

注意修改完重新編譯AppRTC

cd apprtc
grunt build
go install collidermain

4.2 啓動服務

IP用戶名密碼改爲相應的值。

Collider

nohup goWorkspace/bin/collidermain -port=8089 -tls=true -room-server="https://apprtc.lmshao.com:8081" >> log/collider.log &

Coturn

sudo turnserver -v -L 192.168.198.135 -o -a -f -r apprtc.lmshao.com -u liming:12345678 --cer /cert/cert.pem --pkey /cert/key.pem -l log/coturn.log

AppRTC

nohup dev_appserver.py --host apprtc.lmshao.com ./apprtc/out/app_engine --ssl_certificate_path /cert/cert.pem --ssl_certificate_key_path /cert/key.pem --skip_sdk_update_check >> log/apprtc.log &

瀏覽器訪問有如下效果
AppRTC-1

4.3 Nginx反向代理

上面的部署如果使用 https://apprtc.263.net:8081訪問沒問題,一旦使用http://apprtc.263.net:8081 訪問,AppRTC服務就會報錯導致服務卡死,必須重啓AppRTC服務。
可以使用Nginx反向代理方式,設置http自動跳轉到https,並隱藏服務端口。

sudo apt-get install nginx

編輯默認配置文件
/etc/nginx/sites-available/default

# 跳轉到 apprtc.lmshao.com:8081
upstream apprtc {
        server apprtc.lmshao.com:8081;
} 

# http 跳轉到 https
server {
        listen 80;
        server_name apprtc.lmshao.com;
        rewrite ^(.*) https://$server_name$1 permanent;
}

server {
        # SSL configuration
        #
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;

        server_name apprtc.lmshao.com;

        ssl_certificate /cert/cert.pem;
        ssl_certificate_key /cert/key.pem;

        index index.html index.htm index.nginx-debian.html;

        location / {
                #try_files $uri $uri/ =404;
                proxy_pass https://apprtc;
                
                # 必須加這句
                proxy_set_header Host $host;

                # 傳遞遠端IP
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header REMOTE-HOST $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

Nginx 服務管理

# 啓動
sudo nginx
# 停止
sudo pkill -9 nginx

如果沒出錯的話,瀏覽器訪問就可以參會了~
AppRTC-2

5. 總結

主要參考AppRTC的官方文檔進行部署的,摸索了好幾天,遇到了好多坑。目前Web參會沒問題,Android Demo參會有問題,還沒搞定。
東西太多,記錄一下,如果能給後來者參考,少走彎路就更好了。
歡迎交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章