Problems encountered in webrtc+srs project deployment

Since the srs server is used in my project, let’s install the srs service first.

1. Installation of srs

1935 RTMP common port 1985 API interface port 8080 default console access port Here I map to host port 8085

docker run -d --name srs -p 1935:1935 -p 1985:1985 -p 8085:8080 ossrs/srs:5.0.30

After executing the above, continue:

docker cp -a srs:/usr/local/srs/conf /home/srs5/

The purpose of this step is to copy the configuration file from the container to the host’s /home/srs5 directory, because we may configure some other things in the middle, if it is changed inside the container, the container is accidentally deleted, and the configuration history will also be found Not anymore.

docker rm -f srs

Remove the old container, because our goal is to copy the configuration file from it, so after copying, this container does not need to exist, and the container we officially use needs to mount the container started by copying the configuration above.

CANDIDATE is temporary variable, the IP of the current server, if it is a public network server, it is the public network IP user webrtc UDP packet transmission

CANDIDATE="192.168.101.99" docker run --restart=always -d -v /home/srs5/conf/:/usr/local/srs/conf/ -p 1935:1935 -p 1985:1985 -p 8085:8080 \ --env CANDIDATE=$CANDIDATE -p 8000:8000/udp \ ossrs/srs:5.0.30 ./objs/srs -c conf/docker.conf

If the srs service does not respond, execute the following command

  1. view all containers

docker ps -a

  1. delete srs container

docker rm [container id/container name]

Finally, follow the steps above to reinstall srs. You can access the srs console through ip address: 8085.

Second, coturn network penetration server installation

1. Preparation steps

First install various dependencies and software

yum install git

yum install gcc

yum install gcc-c++

yum install openssl

yum install openssl-devel

yum install libevent2

yum install libevent-devel

Choose y for all the options you encounter, and go all the way to y. After the installation is complete

Ready to install the coturn package. Note, do not directly git clone coturn, there will be compilation errors

Install the stable version here, download the compressed package

wget https://github.com/coturn/coturn/archive/4.5.1.1.tar.gz

Then decompress, compile, and execute in sequence

tar -zxvf 4.5.1.1.tar.gz

cd coturn-4.5.1.1

./configure

make

make install

Note that if the folder cannot be found by cd coturn-4.5.1.1, the default installation location of the general installation package is in the /usr/local directory of Alibaba Cloud, just switch to this directory and continue the operation

If successful, it can be verified by which turnserver. If the path is present, it is successful,

2. Configuration folder

Go to the folder:

cd /usr/local/etc/

You will see a configuration file called turnserver.conf.default.

Backup it with the command:

cp turnserver.conf.default turnserver.conf

Then modify the content of the turnserver.conf file

#The IP address monitored by the relay server, directly write the private network IP address in the NAT environment, and multiple IPs can be specified
listening-ip=172.30.124.174
listening-port=3478
#Relay server forwarding address (the local IP address will be used to transmit data packets to each end), it is best to directly write the ip of eth1 output by ip addr, if it does not exist, directly public network IP
relay-ip=120.77.170.59
#External IP, directly write the public network IP address
external-ip=120.77.170.59

Relay thread, if the server resources are sufficient, it can be expanded appropriately, and the maximum number cannot exceed 50

relay-threads=2
# Turn on password authentication and use the short-term certificate mechanism.
lt-cred-mech
#UDP port By default, you can customize the interval you want. This is the port for relay traffic forwarding.
min-port=17001
max-port=19001
#turn server user and credentials
user=longzai:123456
#Open the following DB and close the mysql DB,
userdb=/var/lib/coturn/turndb
## mysql-userdb xxxxxxxxxxxxxxxxxxxx ##Comments

You don’t have to worry about it here, you can configure the corresponding domain name if the public network needs it

realm=example.cn

Configure the log output, and the user will be directly redirected to the container log

log-file=stdout # comment sys-log

After the configuration is complete, execute the following command to start the service

turnserver -v -r your public network ip:3478 -a -o -c /usr/local/etc/turnserver.conf

The figure below is the execution startup

You can test whether the service starts successfully through webrtc.github.io/samples/src….

Note: The returned information of the test service may be inaccurate, and it still needs to be used in the code for testing.

3. Use of coturn

let rtcPcParams = {<!-- -->
 iceServers: [
        {<!-- --> url: "stun:stun.l.google.com:19302"}, // Google's public service
        {<!-- -->urls: 'turn:x.x.x.x:3478', username:'longzai', credential:'123456'}, //turn service self-built can configure multiple
        ]
},

---------------Parameter call location-----------------
pc = new PeerConnection(rtcPcParams)

3. Automatic issuance of SSL certificate

Tool download and install

# Pay attention to replace the email address below with your own
curl https://get.acme.sh | sh -s [email protected]

Turn on automatic updates

acme.sh --upgrade --auto-upgrade

Switch CA type

Currently acme.sh supports four official environment CAs, namely Let’s Encrypt, Buypass, ZeroSSL and SSL.com, and ZeroSSL is used by default. We generally use Let’s Encrypt, which supports both single domain name and wildcard multi-domain name certificates (although the wildcard type certificate is only valid for 3 months, fortunately we have this tool). The command to switch the LE type is as follows:

acme.sh --set-default-ca --server letsencrypt

Fan domain name only supports DNS verification

Applying for an API key (DNSPod Token) To apply for an API Key from Tencent Cloud, the configuration of DNS verification parameters for each vendor is different. If your domain name is not owned by Tencent Cloud, please refer to this document. Then edit the acme tool configuration information, as follows:

cd ~/.acme.sh
vi account.conf
## Add the following dnspod key

#Tencent cloud domain name
export DP_Id="xxxx"
export DP_Key="12222222222"

#Alibaba cloud domain name
export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export Ali_Secret="jlsdflanljkljlfdsaklkjflsa"

Certificate application

Pay attention to the following parameters: dns_dp means verifying with Tencent Cloud dnspos -d webrtc.link -d *.webrtc.link means domain name, please configure your own domain name

If the domain name is Alibaba Cloud, replace dns_dp with dns_ali

The generated certificate and key will be saved under /home/nginxWebUI/letsebcrypt/

acme.sh --iacme.sh --issue --log --dns dns_dp -d webrtc.link -d *.webrtc.link --key-file /home/nginxWebUI/letsebcrypt/private.key -- fullchain-file /home/nginxWebUI/letsebcrypt/cert.crt

If the following figure appears, the certificate is successfully generated.

Project deployment

In order to avoid the problems of cross-domain and different protocols, I use the back-end project to proxy the front-end static resources. The backend service port is 18080

const koa = require("koa");
const router = require("koa-router");
const staticAssets = require("koa-static");
const bodyparse = require("koa-bodyparser");
const cors = require("@koa/cors");
const fs = require("fs");
const path = require("path");

const fileRoutes = require("../router/index");
const errorHandler = require("./errorHandler");

const app = new koa();

// Define middleware to solve the problem of refreshing the page and returning 404 because the resource cannot be found
app. use(async (ctx, next) => {
  // history middleware
  const path = "/dist/"; // path that needs to be judged
  await next(); // wait for the request to complete
  if (ctx. response. status === 404) {
    // Determine if the condition is met
    ctx.type = "text/html; charset=utf-8"; // Modify the response type
    // Note: This path is relative to the project root directory
    ctx.body = fs.readFileSync("./dist/index.html"); // Modify the response body
  }
});
//Proxy static resources
app.use(staticAssets("dist"));

let corsOptions = {
  origin: function (ctx) {
    return "*";
  },
};

app.use(cors(corsOptions));
app. use(bodyparse());
app.fileRoutes = fileRoutes;
app. fileRoutes();

//Listen for errors, handle errors
app.on("error", errorHandler);

module.exports = app;

nginx starts https proxy

server
    {
      server_name longzai1024.top;
      listen 443 ssl http2;
      ssl_certificate /home/nginxWebUI/letsebcrypt/cert.crt;
      ssl_certificate_key /home/nginxWebUI/letsebcrypt/private.key;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
      # http redirect to https
      if ($scheme = http) {
        return 301 https://$host:443$request_uri;
      }
      location / {
        proxy_pass http://49.xxx.51.105:18080/;
        #Here is the service address of the signaling service startup, see the access address in the previous step
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Proto $scheme;
        ## Signaling core configuration must be enabled to support websocket
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_redirecthttp://https://;
      }
    #Proxy srs service address
      location /rtc {
        proxy_pass http://49.xxx.51.105:1985/;
        #Here is the service address of the signaling service startup, see the access address in the previous step
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Proto $scheme;
        ## Signaling core configuration must be enabled to support websocket
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_redirecthttp://https://;
      }
  }

Note: Since our project runs in an https environment, we need to use the https protocol to request domain names for all requests in the project. Including image resources, etc.

Reference link:

www.bilibili.com/read/cv1667…

juejin.cn/book/716841…