搭建coturn作为STUN/TURN服务器帮助webrtc完成NAT穿越

2,217 阅读3分钟

背景

之前做的webrtc记录一次express+socket.io+webrtc实现一对一视频通话 - 掘金 (juejin.cn)最近部署在公网上了,OmgTV,但是在实际的使用中发现视频通信的成功率几乎为零,在 edge 和 chrome 浏览器上可通过 edge://webrtc-internals 或者 chrome://webrtc-internals 访问webrtc的调试工具。调试过后能看到许多的icecandidateerror事件。

于是自己搭建了一个 STRUN/TURN 服务器作为支撑,提高webrtc的通信成功率。我选择的是coturn,是一个主流的开源 STRUN/TURN 服务器。()

搭建步骤

有apt下载以及docker方式的搭建,但都是差不多的。这里以docker为例。需要准备的是一台带有公网ip的云服务器以及已经解析的域名和对应的ssl证书。

文件结构

新建文件夹/www/dockerfiles/coturn,里面编写两个文件: docker-compose.yml 和 turnserver.conf

编写 docker-compose.yml 文件

version: '3'

services:
  coturn:
    image: coturn/coturn
    container_name: coturn
    restart: always
    network_mode: host
    volumes:
      - /www/dockerfiles/coturn/turnserver.conf:/etc/turnserver.conf
      - /etc/ssl:/etc/ssl
    cpus: 1
    mem_limit: 1g
    mem_reservation: 512m

这里挂载卷中的/etc/ssl是我存放ssl证书的地方,按照自己实际情况修改。

/etc/turnserver.conf是coturn的配置文件,我把他挂载在/www/dockerfiles/coturn/turnserver.conf。(如果是apt安装,直接修改本机的/etc/turnserver.conf就好了)

编写 docker-compose.yml 文件


# Listener IP address of relay server. Multiple listeners can be specified.
# If no IP(s) specified in the config file or in the command line options,
# then all IPv4 and IPv6 system IPs will be used for listening.
listening-ip=0.0.0.0

# External IP-Address of the TURN server
external-ip=<服务器的公网ip>

# TURN listener port for UDP and TCP (Default: 3478).
listening-port=3478

# 443 for TURN over TLS, which can bypass firewalls
tls-listening-port=5349

# host domain name.
realm=<自己的域名>

# Path to the SSL certificate and private key.
# Certificate file.
cert=/etc/ssl/<证书的路径>

# Private key file.
pkey=/etc/ssl/<证书私钥的路径>

# Lower and upper bounds of the UDP relay endpoints:
# Further ports that are open for communication
min-port=10000
max-port=20000

user=username:password

# Option to set the log file name.
# By default, the turnserver tries to open a log file in
# /var/log, /var/tmp, /tmp and current directories directories
log-file=/var/log/turnserver.log

# Enable verbose logging
verbose

# Do not allow an TLS/DTLS version of protocol
no-tlsv1
no-tlsv1_1
no-tlsv1_2

注意替换listening-ip 和 realm 和 cert 和 pkey 和 user,这也是为什么我上面的docker-compose.yml挂载了/etc/ssl。其余的配置项也可以自己定义。这里的username和password在使用服务的时候需要。

更改完配置之后,启动docker容器(或者apt安装的重启服务即可)

docker-compose up -d

检查服务运行情况

可能用到的docker相关命令,更详细的可直接查看文档或docker --help

docker ps // 查看docker容器
docker start <container_id> // 运行指定id容器
docker restart <container_id> // 重启指定id容器

apt安装可通过以下命令查看,更详细的可直接查看文档或systemctl --help

systemctl status coturn // 查看coturn服务的运行情况
systemctl start coturn // 开启服务
systemctl stop coturn // 关闭服务
systemctl restart coturn // 重启服务

检查服务器功能

Trickle ICE (webrtc.github.io)

这是一个专门检查STUN/TURN服务器功能的网站

输入:stun:<ip/domain>:3478 并 添加到列表

输入:trun:<ip/domain>:3478 + username + password 并 添加到列表

点击 Gathers candidates,如果结果中出现 srflx,说明STUN的功能正常,如果出现 relay,说明TURN的功能正常。如下图

image.png

应用到webrtc中

安装如下配置上自己的服务器信息即可,每一项webrtc都会尝试连接,注释掉的是一些免费公共的stun,但基本都是失败的,反而还耗时了就把他注释了。

new RTCPeerConnection({
    iceServers: [
        // { urls: 'stun:stun.l.google.com:19302' },
        // { urls: 'stun:stun1.l.google.com:19302' },
        // { urls: 'stun:stun2.l.google.com:19302' },
        // { urls: 'stun:stun.services.mozilla.com' },
        // { urls: 'stun:stun.stunprotocol.org:3478' },
        // { urls: 'stun:stun.sipgate.net:3478' },
        // { urls: 'stun:stun.ideasip.com:3478' },

        { urls: '自己的stun' },
        {
            urls: '自己的turn',
            username: '自己的username',
            credential: '自己的password'
        }
    ]
})

修改完JavaScript代码就可以重新打包部署了。接下就是在公网上愉快的测试自己的webrtc应用了。