Difficulty With Listen Ip's Web Connection

I am hosting a Node server in my own home network with mediasoup on it. It is exposed to the web through NGINX reverse proxy with HTTPS at the NGINX level. After reading documentation many, many times and user questions for multiple days, I am still unable to initiate a device connection over the web. Localhost works fine with the demo when setting my machines local ip but when I try the same base logic In my own service I can not get anything to work.

I have opened the UFW ports 40000 - 49999 in Ubuntu UFW and in NGINX server block using “listen 40000-49999;” and have changed the max allowed workers to 30,000. I also opened the required ports on my router as well.

Here is the server block


server {
    listen 40000-49999;
    server_name xxxxx.net www.xxxxx.net;
    location / {
        proxy_pass http://localhost:7010;
        proxy_http_version 1.1;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/xxxxx.net/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/xxxxx.net/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = www.xxxxx.net) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = xxxxx.net) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name xxxxx.net www.xxxxx.net;
    return 404; # managed by Certbot
}


I am setting my ip’s in the Node server code as such.

const webRtcTransport = {
    listenIps: [
           // Local Ip here                // Web IP here
        { ip: '192.168.1.12', announcedIp: '67.190.57.92'}
    ],
    enableUdp: true,
    enableTcp: true,
    preferUdp: true,
    preferTcp: true,
    maxIncomingBitrate: 1500000,
    initialAvailableOutgoingBitrate: 1000000,
}

 const worker = {
        rtcMinPort: 40000,
        rtcMaxPort: 49999,
        logLevel: 'warn',
        logTags: [
            'info',
            'ice',
            'dtls',
            'rtp',
            'srtp',
            'rtcp',
            'rtx',
            'bwe',
            'score',
            'simulcast',
            'svc'
        ],
    },

I am getting iceCandidates back but this is as far as it gets, nothing else happens in this configuration, there are no errors.

{id: "3e750ba7-17ec-478f-b546-f6ba7127ed71", iceParameters: {…}, iceCandidates: Array(2), dtlsParameters: {…}}
dtlsParameters: {fingerprints: Array(5), role: "auto"}
iceCandidates: (2) [{…}, {…}]
iceParameters: {iceLite: true, password: "vla8qcvstahxhkep8q3xn5s567a621ra", usernameFragment: "igdf5vurols0krdg"}
id: "3e750ba7-17ec-478f-b546-f6ba7127ed71"
__proto__: Object

0: {foundation: "udpcandidate", ip: "67.190.57.92", port: 43415, priority: 1076558079, protocol: "udp", }
1: {foundation: "tcpcandidate", ip: "67.190.57.92", port: 43832, priority: 1076302079, protocol: "tcp", …}

If I do this { ip: ‘67.190.57.92’, announcedIp: null} or almost any other combo, I get the following

 Error: port bind failed due to address not available [transport:udp, ip:'67.190.57.92', port:44957, attempt:1/10000]

This is my client-side code. It gets as far as createSendTransport. The device does not get a connection after. My getRouterRtpCapabilities() returns a successful call to the server with a populated object like so:

{codecs: Array(3), headerExtensions: Array(13)}
codecs: (3) [{…}, {…}, {…}]
headerExtensions: (13) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
const routerRtpCapabilities = await this.socketService.getRouterRtpCapabilities() as RtpCapabilities

await this.device.load({ routerRtpCapabilities })

if (!this.device.canProduce('video')) console.warn('cannot produce video')  // Abort next steps.

//--- Create transport info --- 
const data = await this.socketService.createProducerTransport({
                forceTcp: false,
                rtpCapabilities: this.device.rtpCapabilities,
            }) as TransportOptions

const producerTransport = this.device.createSendTransport(data)

// Resolves to "new"
console.log(producerTransport.connectionState)

producerTransport.on('connect', async ({ dtlsParameters }, callback, errback) => {
       console.log('connected ')
       // this.socketService.request('connectProducerTransport', { dtlsParameters })
       //     .then(callback)
       //     .catch(errback);
})

I fully understand the creator of this library does not like answering certain questions and im not trying to upset him or anyone else with something potentially off topic but I literally have nowhere else to turn on this one. Id love to use this tech but I am completely stuck and the answers are very few out there. Can anyone kindly help me with this issue? Thank you!

Wow, you are opening 10000 in nginx. Why? Nginx is for HTTP/WebSocket. For ICE/RTP it is mediasoup the one that will open ports.

1 Like

Ive done that because I have been trying everything. The docs suggest redirecting the port range to my local port which is why I was trying to do that in NGINX config. Clearly something is up in NGINX or my router, at least from my understanding and I ddo not grasp what exactly the problem is.

Ok, ive already read the docs and tried setting my ip as it recommends as well as redirecting the required ports in my router. That is why I posted here…

You may have problems redirecting UDP/TCP ports. I don’t know. The steps in the FAQ are very common.

1 Like

Thank you for the replies. I will read further.

After reading documentation further I managed to figure it out. It wa a simple mistake on my part. I did not understand the steps in the process and failed to do the following after setting the transport.on events.

// Produce our webcam video.
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const webcamTrack = stream.getVideoTracks()[0];
const webcamProducer = await sendTransport.produce({ track: webcamTrack });
 
// Produce data (DataChannel).
const dataProducer =
  await sendTransport.produceData({ ordered: true, label: 'foo' });

Thank you for your time and responses!