Ubuntu搭建AppRTC本地服务
背景
AppRTC 是由 Google 开发并开源的一个 WebRTC 视频聊天演示应用。它的核心目的是作为 WebRTC 技术的官方参考实现和测试平台,帮助开发者快速理解 WebRTC 的工作原理,并提供一个可实时验证浏览器兼容性与网络环境的工具。为了在内网环境下运行WebRTC Demo,我们搭建了房间服务,信令服务和内网穿透服务。其中房间服务由GAE+AppRTC来启动,信令服务由AppRTC编译生成的collidermain来启动,内网穿透服务由Cotrun来启动,由ICE脚本来对外代理。
我自己的目标是:openharmony下运行ohos_webrtc。所以需要搭建AppRTC服务。
环境准备
需要的库和版本
整套环境基于操作系统:ubuntu20.04,nginx版本:nginx-1.15.8,go语言版本:go1.15.3.linux-amd64, JDK版本:openjdk 11.0.27, Python版本:Python-2.7.9, OpenSSL版本:openssl-1.0.2u, Coturn版本:turnserver-4.5.0.7, GAE版本:google_appengine_1.9.40, Node和Npm采用系统默认版本。
特别注意1:由于ubuntu20.04默认安装了python2.7.18, 这个版本运行google_appengine会报错"cannot import name RAND_egd", 这里我提前写好了一篇文章《Ubuntu20.04安装低版本的Python2.7.9-CSDN博客》,用于安装Python2.7.9版本。
特别注意2:很多源码的下载使用了wget方式获取,你可能需要搭建代理环境,或者直接访问网站下载。具体的代理环境搭建可以参照之前的文章《虚拟机环境下代理下载编译WebRTC源码_ubuntu22 webrtc 下载-CSDN博客》。Ubuntu20.04安装低版本的Python2.7.9-CSDN博客
端口占用图示

端口打开
请提前用如下命令打开占用端口
sudo ufw allow 3478/tcp
sudo ufw allow 3478/udp
sudo ufw allow 8080/tcp
sudo ufw allow 8080/udp
sudo ufw allow 8089/tcp
sudo ufw allow 8089/udp
sudo ufw allow 3033/tcp
sudo ufw allow 3033/udp
搭建流程
我的工作目录是"$HOME/disk3/apprtc_install", 在这里创建apprtc_install目录,接下来安装操作都是在这个目录进行。
cd $HOME/disk3/apprtc_install
mkdir apprtc_install
语言环境准备
JDK安装
sudo apt install -y openjdk-11-jdk
#检查,JDK版没什么影响。
java --version
NodeJs安装
sudo apt install npm -y
sudo apt install nodejs -y
#检查安装
node -v
npm -v
Grunt安装
sudo npm install -g grunt-cli
go语言安装
#当前目录:$HOME/disk3/apprtc_install/
wget https://dl.google.com/go/go1.15.3.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.15.3.linux-amd64.tar.gz
sudo ln -s /usr/local/go/bin/* /usr/bin/
go version
Python语言安装
这里不再赘述,请参照文章《Ubuntu20.04安装低版本的Python2.7.9-CSDN博客》,将python版本降低到2.7.9。
安装服务
安装libevent
这个步骤我参照了其他人的文章,我并没有遇到什么问题,还是照葫芦画瓢安装上。
#当前目录:$HOME/disk3/apprtc_install/
#安装zlib
sudo apt install zlib1g-dev -y
wget https://github.com/downloads/libevent/libevent/libevent-2.1.12-stable.tar.gz
tar xvf libevent-2.1.12-stable.tar.gz
cd libevent-2.1.12-stable
./configure
sudo make install
安装AppRTC
注意: 这里需要代理,下载代码和执行编译都需要,我的代理如下。具体你需要根据我的文章《虚拟机环境下代理下载编译WebRTC源码_ubuntu22 webrtc 下载-CSDN博客》来设置。
export HTTP_PROXY="socks5://192.168.1.103:1234"
export HTTPS_PROXY="socks5://192.168.1.103:1234"
注意:下面执行完go get collidermain,需要切换net分支到release-branch.go1.15,防止编译出错。
#当前目录:$HOME/disk3/apprtc_install/
git clone https://github.com/webrtc/apprtc.git
#这里设置go语言编译&安装目录。
export GOPATH=$HOME/disk3/goworkspace/
mkdir -p $HOME/disk3/goworkspace/src
#将collider的源码软连接到go的工作目录下 (ln -s 软链接,快捷方式)
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
#编译collidermain, 这里因为前面设置了go环境,所以可以在任何目录执行。
go get collidermain
#执行完上面一步骤,会在go环境目录下载net模块,进入这个模块,切换到release-branch.go1.15分支,否则会出错。
cd $GOPATH/src/golang.org/x/net
git checkout -b release-branch.go1.15 origin/release-branch.go1.15
go install collidermain
#运行以上没有打印,可视为成功。
安装 google_appengine
#当前目录:$HOME/disk3/apprtc_install/
wget https://storage.googleapis.com/appengine-sdks/featured/google_appengine_1.9.40.zip
unzip google_appengine_1.9.40.zip
安装CoTrun
#当前目录:$HOME/disk3/apprtc_install/
wget http://coturn.net/turnserver/v4.5.0.7/turnserver-4.5.0.7.tar.gz
tar xfz turnserver-4.5.0.7.tar.gz
cd turnserver-4.5.0.7
./configure
make
sudo make install
安装nginx
sudo apt-get install build-essential zlib1g-dev libpcre3 libpcre3-dev openssl
#当前目录:$HOME/disk3/apprtc_install/
#下载nginx 本文以1.15.8版本为例
wget http://nginx.org/download/nginx-1.15.8.tar.gz
tar xvzf nginx-1.15.8.tar.gz
cd nginx-1.15.8/
# 要支持https请添加--with-http_ssl_module参数
./configure --with-http_ssl_module
# 编译
make
#安装
sudo make install
#建立软链接,后面用到nginx -t
ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/
服务配置与启动
coturn NAT穿透服务器启动
配置stunserver
创建DH秘钥
sudo mkdir /cert
sudo openssl dhparam -out /cert/dhparam.pem 2048
配置turnserver.conf文件,下面的realm=192.168.1.100需要改为自己ubuntu的IP地址,注意user=test:12345。
#当前目录:$HOME/disk3/apprtc_install
#新建turnserver.conf, 然后编写报错。
vi turnserver.conf
#填写如下内容
listening-ip=0.0.0.0
external-ip=192.168.1.100
relay-ip=192.168.1.100
listening-port=3478
tls-listening-port=5349
#本地监听的网卡设备,这里根据自己的实际情况填写
#网卡名通过ip link show 命令查看
#listening-device=ens33
#relay-device=ens33
#指定的转发端口的分配范围,测试时,可以将防火墙全部关闭,防止 UDP 端口被屏蔽
min-port=3480
max-port=3500
relay-threads=4
#日志输出级别,turnserver 启动时加上 -v,可以得到更清晰的日志输出
Verbose
#消息验证,WebRTC 的消息里会用到
fingerprint
#webrtc 通过 turn 中继,必须使用长验证方式
lt-cred-mech
# ICE REST API 认证需要(如果打开了这行,turn就不工作了)
#use-auth-secret
user=test:12345
# REST API 加密所需的 KEY
# 这里我们使用“静态”的 KEY,Google 自己也用的这个
static-auth-secret=test
#用户登录域,下面的写法可以不改变它,因为再启动 turnserver 时,可以通过指定参数覆盖它
realm=192.168.1.100
#屏蔽 loopback, multicast IP地址的 relay
no-loopback-peers
no-multicast-peers
#启用 Mobility ICE 支持(不懂)
mobility
#禁用本地 telnet cli 管理接口
no-cli
cert=/cert/cert.pem
pkey=/cert/key.pem
dh-file=/cert/dhparam.pem
启动turnserver服务
sudo turnserver -v -f -r 192.168.1.100 -c $HOME/disk3/apprtc_install/turnserver.conf
#开启新窗口 执行查看端口使用正常。
netstat -ntulp | grep turnserver
collider 信令服务器启动
秘钥&证书配置
签名时,默认回车键即可。
#创建自签名的数字证书
#如果没有openssl,需要安装
sudo mkdir -p /cert
cd /cert
# CA私钥
sudo openssl genrsa -out key.pem 2048
# 自签名证书
sudo openssl req -new -x509 -key key.pem -out cert.pem -days 1095
启动Collider服务
Terminal中新建TAB页面启动。
#启动命令如下。
sudo $HOME/disk3/goworkspace/bin/collidermain -port=8089 -tls=true -room-server="https://192.168.1.100:8090"
#验证启动成功
sudo netstat -tulpn | grep collider
#打印如下。
tcp6 0 0 :::8089 :::* LISTEN 80165/collidermain
APPRTC房间服务启动
APPRTC服务配置修改
1)修改apprtc/src/app_engine/constants.py文件,注意:192.168.1.100 是我的内网IP,你们需要改为自己ubuntu的地址。其他端口号保持一致。这里配置了WSS/WS地址,ICE HTTP服务地址,TURN&STUN的服务地址。
diff --git a/src/app_engine/constants.py b/src/app_engine/constants.py
index 682331b..99a80c3 100644
--- a/src/app_engine/constants.py
+++ b/src/app_engine/constants.py
@@ -22,38 +22,43 @@ LOOPBACK_CLIENT_ID = 'LOOPBACK_CLIENT_ID'
# 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:hostname/IpToTurnServer:19305?transport=udp",
-# "turn:hostname/IpToTurnServer:19305?transport=tcp"
-# ],
-# "username": "TurnServerUsername",
-# "credential": "TurnServerCredentials"
-# },
-# {
-# "urls": [
-# "stun:hostname/IpToStunServer:19302"
-# ]
-# }
-# ]
-
-ICE_SERVER_BASE_URL = 'https://appr.tc'
+ICE_SERVER_OVERRIDE = [
+ {
+ "urls": [
+ "turn:192.168.1.100:3478?transport=udp",
+ "turn:192.168.1.100:3478?transport=tcp",
+ "turns:192.168.1.100:5349?transport=tcp"
+ ],
+ "username": "test",
+ "credential": "12345"
+ },
+ {
+ "urls": [
+ "stun:192.168.1.100:3478"
+ ]
+ }
+]
+
+#ICE_SERVER_BASE_URL = 'https://appr.tc'
+ICE_SERVER_BASE_URL = 'https://192.168.1.100:8088'
ICE_SERVER_URL_TEMPLATE = '%s/v1alpha/iceconfig?key=%s'
ICE_SERVER_API_KEY = os.environ.get('ICE_SERVER_API_KEY')
HEADER_MESSAGE = os.environ.get('HEADER_MESSAGE')
ICE_SERVER_URLS = [url for url in os.environ.get('ICE_SERVER_URLS', '').split(',') if url]
# Dictionary keys in the collider instance info constant.
-WSS_INSTANCE_HOST_KEY = 'host_port_pair'
+#WSS_INSTANCE_HOST_KEY = 'host_port_pair'
+WSS_INSTANCE_HOST_KEY = '192.168.1.100:8089'
WSS_INSTANCE_NAME_KEY = 'vm_name'
WSS_INSTANCE_ZONE_KEY = 'zone'
WSS_INSTANCES = [{
- WSS_INSTANCE_HOST_KEY: 'apprtc-ws.webrtc.org:443',
+# WSS_INSTANCE_HOST_KEY: 'apprtc-ws.webrtc.org:443',
+ WSS_INSTANCE_HOST_KEY: '192.168.1.100:8089',
WSS_INSTANCE_NAME_KEY: 'wsserver-std',
WSS_INSTANCE_ZONE_KEY: 'us-central1-a'
}, {
- WSS_INSTANCE_HOST_KEY: 'apprtc-ws-2.webrtc.org:443',
+# WSS_INSTANCE_HOST_KEY: 'apprtc-ws-2.webrtc.org:443',
+ WSS_INSTANCE_HOST_KEY: '192.168.1.100:8089',
WSS_INSTANCE_NAME_KEY: 'wsserver-std-2',
WSS_INSTANCE_ZONE_KEY: 'us-central1-f'
}]
2)修改src/web_app/js/appcontroller.js,防止报错"Failed to execute 'pushState' on 'History'"。修改内容如下。
diff --git a/src/web_app/js/appcontroller.js b/src/web_app/js/appcontroller.js
index 16a75d5..a000e8e 100644
--- a/src/web_app/js/appcontroller.js
+++ b/src/web_app/js/appcontroller.js
@@ -434,6 +434,7 @@ AppController.prototype.pushCallNavigation_ = function(roomId, roomLink) {
};
AppController.prototype.displaySharingInfo_ = function(roomId, roomLink) {
+ roomLink=roomLink.replace("http","https");
this.roomLinkHref_.href = roomLink;
this.roomLinkHref_.text = roomLink;
this.roomLink_ = roomLink;
APPRTC编译
#当前目录在$HOME/disk3/app_install/
#进入apprtc目录
cd apprtc
#安装依赖包
npm install
#编译
grunt build
APPRTC房间服务启动
Terminal中新建TAB页面启动。
如果遇到SSL等错误,请查看“Python语言安装部分”。
#启动命令
$HOME/disk3/apprtc_install/google_appengine/dev_appserver.py --host=192.168.1.100 --port=8090 $HOME/disk3/apprtc_install/apprtc/out/app_engine --skip_sdk_update_check
#启动后打印如下
INFO 2025-07-20 15:42:27,817 devappserver2.py:769] Skipping SDK update check.
INFO 2025-07-20 15:42:27,832 api_server.py:205] Starting API server at: http://localhost:38057
INFO 2025-07-20 15:42:27,838 dispatcher.py:197] Starting module "default" running at: http://192.168.1.100:8090
INFO 2025-07-20 15:42:27,838 admin_server.py:116] Starting admin server at: http://localhost:8000
ICE启动
ICE配置
编写启动JS文件,拷贝即可。
#当前目录在$HOME/disk3/app_install/
#创建一个新目录
mkdir iceService
#创建新文件编辑保存
touch ice.js
#编辑
vi ice.js
#填写如下内容
var http = require('http');
var crypto = require('crypto')
var hmac = function(key, content) {
var method = crypto.createHmac('sha1', key)
method.setEncoding('base64')
method.write(content)
method.end()
return method.read()
}
http.createServer(function(request, response) {
//账户
var timestamp = Math.floor(Date.now() / 1000)
var turn_username = timestamp + ':audos'
//密码
var key = '12345'
var password = hmac(key, turn_username)
// 发送 HTTP 头部
// HTTP 状态值: 200 : OK
// 内容类型: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
console.log(turn_username);
console.log(password);
// 发送响应数据 "ice服务器"
response.end('{"iceServers":[{"username":"'+turn_username+'","credential":"'+password+'","urls":["stun:192.168.1.100:3478","turn:192.168.1.100:3478"]}]}'); }).listen(8088);
// 终端打印如下信息
console.log('ICE Server running');
启动ICE命令
sudo node $HOME/disk3/apprtc_install/iceService/ice.js
nginx服务配置
配置nginx加入service列表
sudo vi /etc/systemd/system/nginx.service
#内容如下。
Description=The Nginx HTTP Server
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target
启动nginx服务
#测试nginx配置
sudo nginx -t
#启动nginx服务
sudo systemctl daemon-reload
sudo systemctl start nginx
#nginx开机自动启动。
sudo systemctl enable nginx
#访问主页
curl http://localhost/
#可打印网页即成功。
配置nginx conf文件
注意配置文件里包含了子配置/usr/local/nginx/conf/conf.d/apprtc.conf
#编辑配置文件
sudo vi /usr/local/nginx/conf/nginx.conf、
#配置文件最终如下
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
include /usr/local/nginx/conf/conf.d/apprtc.conf;
}
需要在目录/usr/local/nginx/conf/conf.d/下创建apprtc.conf,配置详情如下:
#编辑文件
vi /usr/local/nginx/conf/conf.d/apprtc.conf
#填入一下内容
upstream roomserver {
server 192.168.1.100:8090;
}
server {
listen 80;
server_name 192.168.1.100;
return 301 https://$server_name$request_uri;
}
server {
root usr/share/nginx/html;
index index.php index.html index.htm;
listen 443 ssl;
ssl_certificate /cert/cert.pem;
ssl_certificate_key /cert/key.pem;
server_name 192.168.1.100;
location / {
proxy_pass http://roomserver$request_uri;
proxy_set_header Host $host;
}
}
语法检查
nginx -t
重新启动nginx服务
sudo systemctl restart nginx
启动命令汇总
#启动stun&turn
sudo turnserver -v -f -r 192.168.1.100 -c $HOME/disk3/apprtc_install/turnserver.conf
#启动信令服务器
sudo $HOME/disk3/goworkspace/bin/collidermain -port=8089 -tls=true -room-server="https://192.168.1.100:8090"
#启动房间
$HOME/disk3/apprtc_install/google_appengine/dev_appserver.py --host=192.168.1.100 --port=8090 $HOME/disk3/apprtc_install/apprtc/out/app_engine --skip_sdk_update_check
#启动ICE
sudo node /home/lxf/disk3/apprtc_install/iceService/ice.js
#启动nginx
sudo systemctl restart nginx
更多推荐



所有评论(0)