Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remote video blank inside of docker container / elastic beanstalk #2

Open
imgntn opened this issue Jun 26, 2019 · 11 comments
Open

remote video blank inside of docker container / elastic beanstalk #2

imgntn opened this issue Jun 26, 2019 · 11 comments

Comments

@imgntn
Copy link

imgntn commented Jun 26, 2019

if i try to expose port 3000 and run the examples inside of a docker container (on my localhost for now), the remote video of all examples is always blank. any advice?

@imgntn imgntn changed the title remote video blank inside of docker container remote video blank inside of docker container / elastic beanstalk Jun 28, 2019
@imgntn
Copy link
Author

imgntn commented Jun 28, 2019

same result running the examples on elastic beanstalk. i'm guessing there are a range of ports that need to be exposed for webRTC to work... how do I find out what they are? Thanks!! :)

@imgntn
Copy link
Author

imgntn commented Jun 28, 2019

related? node-webrtc/node-webrtc#416

@xtapac
Copy link

xtapac commented Aug 29, 2019

@imgntn I found that for correct remote execution it is necessary to set ICE server in the webrtcconnection.js:

const peerConnection = new RTCPeerConnection({ sdpSemantics: 'unified-plan', iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });

@tzvc
Copy link

tzvc commented Nov 27, 2019

Any update on this? I'm trying to run the video-composing example in a Docker container but only HTTP calls are let through, do we need to have a special port configuration for WEBRTC to work here?

@tzvc
Copy link

tzvc commented Dec 2, 2019

@xtapac What I don't get here is that the example doesn't provide a way for the peers (here, client and server) to exchange ICE candidates. Did you have to implement it yourself as an endpoint or something?

@markandrus
Copy link
Member

@theochampion the way the signaling between client and server works assumes that the server discovers host candidates that the client can reach. Take a look at lib/server/connections/webrtcconnection.js: the server waits until ICE gathering is complete (and therefore the server’s localDescription contains all gathered host candidates) before returning its offer to the client. The client never exchanges ICE candidate strings with the server. Instead, assuming the client can indeed reach one or more of the server’s host candidates, the server will discover the client’s peer-reflexive candidates.

Regarding Docker, it could be that the host candidates advertised by the server are not reachable by the client (maybe they reference some IP only known within the Docker container). This could be verified by looking at the SDP generated by the server. If this is the case, the ICE server fix described above is a workaround. It might also be fine to just rewrite the IP addresses in the host candidates to the Docker container’s IP(s).

@tzvc
Copy link

tzvc commented Dec 2, 2019

@markandrus Thanks for the reply. So If I understand well, the server generate a list of candidates for the client to try and just "wait" for the data to arrive from the WebRTCConnection ?

Here is the list of candidates sent from my server in the SDP offer

c=IN IP4 35.181.61.8
a=rtcp:9 IN IP4 0.0.0.0
a=candidate:211781638 1 udp 2122260223 172.31.26.2 45893 typ host generation 0 network-id 1
a=candidate:2780825555 1 udp 1686052607 35.181.61.8 45893 typ srflx raddr 172.31.26.2 rport 45893 generation 0 network-id 1
a=candidate:1109161206 1 tcp 1518280447 172.31.26.2 44409 typ host tcptype passive generation 0 network-id 1

Here 35.181.61.8 is the public IP of my server (accessible from the client) and 172.31.26.2 is the private IP.
From what I see here, this candidate:

a=candidate:2780825555 1 udp 1686052607 35.181.61.8 45893 typ srflx raddr 172.31.26.2 rport 45893 generation 0 network-id 1

Should allow the client to connect.

But if I inspect the webrtcconnection client side using chrome://webrtc-internals/ is appears that only ice condidates of type host are evaluated which is weird because my iceTransportPolicy is set to all.

Screen Shot 2019-12-02 at 7 33 13 pm

Any ideas?

Also, i've noticed this function

function disableTrickleIce(sdp) {
  return sdp.replace(/\r\na=ice-options:trickle/g, '');
}

that modify the SDP, what exactly does that do and should I be using it?

Cheers!

Edit : I found this post that seems to talk about the issue, but I'm no sure I understand https://groups.google.com/forum/#!topic/discuss-webrtc/MhjXHbaexLw

@markandrus
Copy link
Member

@theochampion

Thanks for the reply. So If I understand well, the server generate a list of candidates for the client to try and just "wait" for the data to arrive from the WebRTCConnection ?

Yes

a=candidate:2780825555 1 udp 1686052607 35.181.61.8 45893 typ srflx raddr 172.31.26.2 rport 45893 generation 0 network-id 1

I guess you get this srflx candidate because you modified the server code to include ICE servers when configuring the RTCPeerConnection?

But if I inspect the webrtcconnection client side using chrome://webrtc-internals/ is appears that only ice condidates of type host are evaluated which is weird because my iceTransportPolicy is set to all.

The logs are showing "icecandidate" events generated in the browser, i.e., local candidates gathered by the browser. No STUN servers are configured, therefore no srflx candidates are gathered. Only host.

@markandrus
Copy link
Member

Here is some information for anyone else trying to use Docker: the type of networking used is important. Notice that, if I use the default bridge network, node-webrtc inside the container is only going to discover its Docker bridge IP (172.17.0.2 in this example):

$ docker run --rm -t foo docker | grep '^candidate:'
candidate:4112619227 1 udp 2122260223 172.17.0.2 55607 typ host generation 0 ufrag 0lwU network-id 1
candidate:1510613869 1 udp 2122194687 127.0.0.1 39220 typ host generation 0 ufrag 0lwU network-id 2
candidate:3147983403 1 tcp 1518280447 172.17.0.2 46177 typ host tcptype passive generation 0 ufrag 0lwU network-id 1
candidate:344579997 1 tcp 1518214911 127.0.0.1 37497 typ host tcptype passive generation 0 ufrag 0lwU network-id 2

However, if I specify the host network, node-webrtc inside the container is going to discover the host's IP (in this case, my laptop—192.168.65.3—however, this could be an EC2 instance, or some other hosted service):

$ docker run --rm --network host -t foo docker | grep '^candidate:'
candidate:2948193667 1 udp 2122260223 192.168.65.3 60905 typ host generation 0 ufrag 20/8 network-id 1
candidate:559267639 1 udp 2122202367 ::1 41123 typ host generation 0 ufrag 20/8 network-id 3
candidate:1510613869 1 udp 2122129151 127.0.0.1 33104 typ host generation 0 ufrag 20/8 network-id 2
candidate:3778683251 1 tcp 1518280447 192.168.65.3 46337 typ host tcptype passive generation 0 ufrag 20/8 network-id 1
candidate:1876313031 1 tcp 1518222591 ::1 55243 typ host tcptype passive generation 0 ufrag 20/8 network-id 3
candidate:344579997 1 tcp 1518149375 127.0.0.1 45843 typ host tcptype passive generation 0 ufrag 20/8 network-id 2

Dockerfile, for reference:

# docker/Dockerfile
FROM node:14-alpine AS base
RUN apk update && apk add --no-cache alsa-lib
RUN ln -s /lib/libc.musl-x86_64.so.1 /lib/ld-linux-x86-64.so.2
RUN DEBUG=true npm install wrtc
ENTRYPOINT ["node", "-e", "var pc = new (require('wrtc').RTCPeerConnection); pc.addTransceiver('audio'); pc.createOffer().then(offer => pc.setLocalDescription(offer)); pc.onicecandidate = event => { if (event.candidate) { console.log(event.candidate.candidate) } else { process.exit() } }"]

@regnaio
Copy link

regnaio commented Dec 18, 2020

same result running the examples on elastic beanstalk. i'm guessing there are a range of ports that need to be exposed for webRTC to work... how do I find out what they are? Thanks!! :)

Just ran into this issue too, and I think imgntn's explanation is why the webrtc UDP connection is failing in Docker

@regnaio
Copy link

regnaio commented Aug 23, 2023

Here is some information for anyone else trying to use Docker: the type of networking used is important. Notice that, if I use the default bridge network, node-webrtc inside the container is only going to discover its Docker bridge IP (172.17.0.2 in this example):

$ docker run --rm -t foo docker | grep '^candidate:'
candidate:4112619227 1 udp 2122260223 172.17.0.2 55607 typ host generation 0 ufrag 0lwU network-id 1
candidate:1510613869 1 udp 2122194687 127.0.0.1 39220 typ host generation 0 ufrag 0lwU network-id 2
candidate:3147983403 1 tcp 1518280447 172.17.0.2 46177 typ host tcptype passive generation 0 ufrag 0lwU network-id 1
candidate:344579997 1 tcp 1518214911 127.0.0.1 37497 typ host tcptype passive generation 0 ufrag 0lwU network-id 2

However, if I specify the host network, node-webrtc inside the container is going to discover the host's IP (in this case, my laptop—192.168.65.3—however, this could be an EC2 instance, or some other hosted service):

$ docker run --rm --network host -t foo docker | grep '^candidate:'
candidate:2948193667 1 udp 2122260223 192.168.65.3 60905 typ host generation 0 ufrag 20/8 network-id 1
candidate:559267639 1 udp 2122202367 ::1 41123 typ host generation 0 ufrag 20/8 network-id 3
candidate:1510613869 1 udp 2122129151 127.0.0.1 33104 typ host generation 0 ufrag 20/8 network-id 2
candidate:3778683251 1 tcp 1518280447 192.168.65.3 46337 typ host tcptype passive generation 0 ufrag 20/8 network-id 1
candidate:1876313031 1 tcp 1518222591 ::1 55243 typ host tcptype passive generation 0 ufrag 20/8 network-id 3
candidate:344579997 1 tcp 1518149375 127.0.0.1 45843 typ host tcptype passive generation 0 ufrag 20/8 network-id 2

Dockerfile, for reference:

# docker/Dockerfile
FROM node:14-alpine AS base
RUN apk update && apk add --no-cache alsa-lib
RUN ln -s /lib/libc.musl-x86_64.so.1 /lib/ld-linux-x86-64.so.2
RUN DEBUG=true npm install wrtc
ENTRYPOINT ["node", "-e", "var pc = new (require('wrtc').RTCPeerConnection); pc.addTransceiver('audio'); pc.createOffer().then(offer => pc.setLocalDescription(offer)); pc.onicecandidate = event => { if (event.candidate) { console.log(event.candidate.candidate) } else { process.exit() } }"]

Great info, thanks markandrus!

This may explain why WebRTC in Docker Windows hasn't been working for a while

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants