• AppRTC 最初是由 Google(以及社区)推出的一个演示应用,用来展示 WebRTC 在浏览器之间进行实时音视频通信的能力。
  • 仓库首页注明:该 demo 服务(例如 appr.tc )已被关闭,推荐使用 Docker 部署自己的测试/开发实例.
  • 它并不是一个完整商业级产品,而更多是一个“参考实现”或“起步模板”——你可以拿它来看、改、用作启动你的 WebRTC 应用。
  • 在 WebRTC 的 “参考应用(Reference Apps)”列表中,AppRTC 被列为一个浏览器间通话的示例。

拉取代码

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

官方文档上docker部署的步骤是直接下载Dockerfile文件,但是由于后续有部分自定义操作,所以个人推荐把源码个拉下来。

构建 Docker 镜像

sudo docker build apprtc/

这条命令会把 apprtc/ 目录里的 Dockerfile 用来生成一个可以运行 AppRTC 的容器镜像。

Dockerfile文件指令讲解

  1. 基础镜像和环境准备

    FROM golang:1.17.5-alpine3.15
       
    RUN apk add --no-cache git curl python2 build-base openssl-dev openssl 
    RUN git clone https://github.com/webrtc/apprtc.git
    
    • FROM golang:1.17.5-alpine3.15 选择 Go 语言 + Alpine Linux 作为基础镜像,轻量、适合编译 Go 程序。

    • apk add ... 安装依赖工具:gitcurlpython2、编译工具 (build-base)、OpenSSL 库。

    • git clone 克隆 AppRTC 的源码到镜像里。

  2. 安装 Google App Engine (GAE) SDK

    RUN curl https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-367.0.0-linux-x86_64.tar.gz --output gcloud.tar.gz \
        && tar -xf gcloud.tar.gz \
        && google-cloud-sdk/bin/gcloud components install app-engine-python-extras app-engine-python cloud-datastore-emulator --quiet \
        && rm -f gcloud.tar.gz
    
    • 下载 Google Cloud SDK,用于运行 GAE Python 应用

    • 安装必要组件:app-engine-python-extrasapp-engine-pythoncloud-datastore-emulator

    • 清理安装包以减小镜像体积。

  3. 构建 AppRTC GAE 应用

    RUN python apprtc/build/build_app_engine_package.py apprtc/src/ apprtc/out/ \
        && curl https://webrtc.github.io/adapter/adapter-latest.js --output apprtc/src/web_app/js/adapter.js \
        && cp apprtc/src/web_app/js/*.js apprtc/out/js/
    
    • 运行 Python 脚本打包 AppRTC 的 GAE 应用到 out/ 目录。

    • 下载最新的 WebRTC Adapter.js并复制到输出目录。

  4. 创建启动脚本

    RUN echo -e "#!/bin/sh\n" > /go/start.sh \
        && echo -e "`pwd`/google-cloud-sdk/bin/dev_appserver.py --host 0.0.0.0 `pwd`/apprtc/out/app.yaml &\n" >> /go/start.sh
    
    • 创建一个 start.sh 脚本,用来启动 GAE 开发服务器 (dev_appserver.py) 并监听所有网络接口。

    • & 表示后台运行,这样可以同时启动其他服务。

  5. 设置 Collider (WebRTC 信令服务器)

    RUN export GOPATH=$HOME/goWorkspace/ \
        && go env -w GO111MODULE=off
       
    RUN ln -s `pwd`/apprtc/src/collider/collidermain $GOPATH/src \
        && ln -s `pwd`/apprtc/src/collider/collidertest $GOPATH/src \
        && ln -s `pwd`/apprtc/src/collider/collider $GOPATH/src \
        && cd $GOPATH/src \
        && go get collidermain \
        && go install collidermain
       
    # Add Collider executable to the start.sh bash script.
    RUN echo -e "$GOPATH/bin/collidermain -port=8089 -tls=true -room-server=http://localhost &\n" >> /go/start.sh
    
    • 设置 Go 工作空间 GOPATH,因为 Collider 是用 Go 写的。

    • 链接源代码并编译 collidermain 可执行文件。

    • 把 Collider 启动命令添加到 start.sh,监听 8089 端口并启用 TLS。

  6. 安装并配置 stunnel (TLS/SSL 隧道)

    RUN curl  https://www.stunnel.org/archive/5.x/stunnel-${STUNNEL_VERSION}.tar.gz --output stunnel.tar.gz\
        && tar -xf /usr/src/stunnel.tar.gz
    WORKDIR /usr/src/stunnel-${STUNNEL_VERSION}
    RUN ./configure --prefix=/usr && make && make install
    
    • 下载、编译 stunnel,用于将 HTTP 服务包装成 HTTPS(加密传输)。
    RUN mkdir /cert
    RUN openssl req -x509 -out /cert/cert.crt -keyout /cert/key.pem \
      -newkey rsa:2048 -nodes -sha256 \
      -subj '/CN=localhost' -extensions EXT -config <( \
       printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth") \
      && cat /cert/key.pem > /cert/cert.pem \
      && cat /cert/cert.crt >> /cert/cert.pem \
      && chmod 600 /cert/cert.pem /cert/key.pem /cert/cert.crt
         
    RUN echo -e "foreground=yes\n" > /usr/etc/stunnel/stunnel.conf \
        && echo -e "[AppRTC GAE]\n" >> /usr/etc/stunnel/stunnel.conf \ 
        && echo -e "accept=0.0.0.0:443\n" >> /usr/etc/stunnel/stunnel.conf \
        && echo -e "connect=0.0.0.0:8080\n" >> /usr/etc/stunnel/stunnel.conf \
        && echo -e "cert=/cert/cert.pem\n" >> /usr/etc/stunnel/stunnel.conf 
       
    RUN echo -e  "/usr/bin/stunnel &\n" >> /go/start.sh \
        && echo -e "wait -n\n" >> /go/start.sh \
        && echo -e "exit $?\n" >> /go/start.sh \
        && chmod +x /go/start.sh
    
    • 生成自签名证书用于 TLS。
    • 配置 stunnel,将外部 HTTPS 请求转发到本地的 HTTP 服务(端口 8080)。
    • 将 stunnel 启动命令加入 start.sh
  7. 最终启动命令

    CMD /go/start.sh
    
    • 运行 start.sh
      1. AppRTC GAE 应用
      2. Collider 信令服务器
      3. stunnel TLS 隧道

运行 Docker 镜像

  1. 查询刚刚创建好的镜像

    sudo docker images
    

    记录IMAGE ID : 2546b3f6f972

  2. 运行 Docker 镜像

    sudo docker run -p 443:443 -p 8089:8089 --rm -ti 2546b3f6f972
    
      说明
    docker run 创建并运行一个新的容器
    -p 443:443 主机的 443 端口 映射到 容器的 443 端口(容器内 stunnel 的 HTTPS 服务)
    -p 8089:8089 主机的 8089 端口 映射到 容器的 8089 端口(容器内 Collider 信令服务)
    --rm 容器退出后自动删除,不保留残留数据
    -ti 分配伪终端并启用交互模式(-t 分配 TTY,-i 保持输入)
    503621f4f7bd 镜像 ID

进入AppRTC 测试页面

https://localhost/?wshpp=localhost:8089&wstls=true

局域网IP访问

  1. 查询当前IP

    ip a
    

    找到主机ip

  2. 使用IP替换localhost(假设ip为172.22.193.168)

    https://172.22.193.168/?wshpp=172.22.193.168:8089&wstls=true

    Request host is not whitelist enabled for this server. Please use the –host command-line flag to whitelist a specific host (recommended) or use –enable_host_checking to disable host checking. See the command-line flags help text for more information.

    dev_appserver.py 默认会检查 Host 白名单,如果你的请求不是来自默认允许的 localhost / 127.0.0.1 就会出现该错误。

    解决方案:

    1. 打开Dockerfile文件

    2. 找到dev_appserver.py, 并添加参数(enable_host_checking=false)关闭 Host 检查

      RUN echo -e "#!/bin/sh\n" > /go/start.sh \
          && echo -e "`pwd`/google-cloud-sdk/bin/dev_appserver.py --host 0.0.0.0 --enable_host_checking=false `pwd`/apprtc/out/app.yaml &\n" >> /go/start.sh
      
    3. 重启构建并运行镜像

      # 构建
      sudo docker build apprtc/
      # 查询镜像
      sudo docker images
      # 运行镜像
      sudo docker run -p 443:443 -p 8089:8089 --rm -ti <镜像ID>
      
    4. 再次访问https://172.22.193.168/?wshpp=172.22.193.168:8089&wstls=true

进入房间

点击JOIN进入房间页面,由于电脑没有摄像头,这里使用手机测试。

在浏览器打印错误信息 Access to XMLHttpRequest at ‘https://appr.tc/v1alpha/iceconfig?key=’ from origin ‘https://172.22.193.168’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. POST https://appr.tc/v1alpha/iceconfig?key= net::ERR_FAILED 405 (Method Not Allowed)

ICE 服务器请求失败,https://appr.tc/v1alpha/iceconfig?key=产生的跨域问题。

解决方案: 自建 TURN/STUN 服务器

配置ICE_SERVER

打开apprtc/src/app_engine/constants.py

修改ICE_SERVER_OVERRIDE参数

ICE_SERVER_OVERRIDE = [
  {
    "urls": [
      "stun:172.22.193.168:3478"
    ]
  },
  {
    "urls": [
      "turn:172.22.193.168:3478?transport=udp",
      "turn:172.22.193.168:3478?transport=tcp"
    ],
    "username": "turnuser",
    "credential": "turnpassword"
  }
]

修改Dockerfile

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

# git clone 后(或直接用本地源码),覆盖 constants.py
COPY src/app_engine/constants.py apprtc/src/app_engine/constants.py  


# localhost替换成IP
RUN openssl req -x509 -out /cert/cert.crt -keyout /cert/key.pem \
  -newkey rsa:2048 -nodes -sha256 \
  -subj '/CN=172.22.193.168' -extensions EXT -config <( \
   printf "[dn]\nCN=172.22.193.168\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=IP:172.22.193.168\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth") \
  && cat /cert/key.pem > /cert/cert.pem \
  && cat /cert/cert.crt >> /cert/cert.pem \
  && chmod 600 /cert/cert.pem /cert/key.pem /cert/cert.crt

重启构建并运行镜像

# 构建
sudo docker build apprtc/
# 查询镜像
sudo docker images
# 运行镜像
sudo docker run -p 443:443 -p 8089:8089 --rm -ti <镜像ID>

测试成果

两个Android手机打开浏览器进入https://172.22.193.168/?wshpp=172.22.193.168:8089&wstls=true,输入相同的ROOM ID.