why does WebRTC require both browsers to generate connection info? - webrtc

So I am looking into building a game using WebRTC, mostly just to learn how to use WebRTC more than anything. What I envisioned in my head was one browser (lets call it Alice) wants to start a game. They figure out their connection information and then send that info to another browser (Bob) who they want to join their game. I like the idea of a link similar to a discord invite.
What I had imagined, was that this was all that was required. Bob's browser knows where Alice is, and Alice is expecting a connection from someone who knows about their connection information (their SDP). Instead what is required is that Bob needs to generate his own connection information (his SDP) and then hand that back to Alice somehow. (For reference, here is an implementation of a "serverless" WebRTC client, which requires both parties to pass their connection info to the other person https://github.com/lesmana/webrtc-without-signaling-server)
Because there are two required messages, telling users to do this manually is very much a pain, and gets increasingly difficult with more users (e.g. Alice, Bob and Charlie want to connect). For this reason we have "signaling servers" which handle this handshaking.
My question is why is all of this necessary? Is it for security? Couldnt you consider a browser secure enough if their SDP info included a generated hash that only those they expect (like Bob) have access to?

Don't confuse connection info (ice candidates) with SDP.
What are ICE Candidates and how do the peer connection choose between them?
If you are asking specifically about web browsers - then yes, you have to collect connection info, nothing to do with SDP, from each browser. This is because browsers do not listen on a specific, well known port, which is open in firewalls too. So it's not like one browser could just connect to another one, using well-known endpoint (IP:Port).
The idea is that Stun server will drill a hole in both firewalls and thus will make direct connection between browsers possible. Read STUN spec to see how this is done.
However, if one peer is a browser, and another peer is your own application that listens on specific port (WebRTC gateways, media servers), then you don't need to collect connection info (ice candidates) from the browser. Nobody needs it. Stun/Turn servers are not involved. Browser always connects to your application. You can hardcode ice candidate in your webpage, which will contain the endpoint exposed by your application.
You always have to exchange SDPs between two peers, because they carry codecs information and other info about media stream, that another peer needs to know about. Browsers need to agree that they can decode the incoming stream, for example.

Related

Do both endpoints in WebRTC need STUN/TURN config/credentials

Working in WebRTC, it would seem like only the offering client would need to provide STUN and TURN locations and credentials that would be encased in the offer and then used by the receiving client(s). Is that the case? If not, why not?
No, clients on both ends need to provide some sort of STUN/TURN configuration, note that these configurations need not to be the same.
Recall that STUN and TURN just provides you the tools to get around NAT. In other words, it provides the tools for a peer to figure out a way to be reachable publicly. They do that by generating ICE candidates that we send through signalling. As long as we can generate at least one valid ICE candidate and tell our peer about it, we can establish a connection.
The reason why both ends need to provide configuration is because otherwise, one of the peers would have no way to tell which IP address belongs to the other. Therefore, even though the answering peer has your ICE candidates (so it knows how to reach you), if the ICE candidates are generated only by the offering side, then this side has no way to securely tell that an incoming connection attempt is actually coming from the peer who you sent your offer to (although it most likely would be).
And for the bounty question "I would like to know if it's possible to connect peers over TURN when only one peer has the required TURN credentials.", the answer is also no.
To understand why, you need to understand that a TURN server is there so in case you can't establish a direct connection due to firewalls, incompatibilities, etc. it generates you "fake" ICE candidates to send to your peer because, in reality, these candidates are actually representing your TURN server. Your TURN server would then relay data sent by your peer to you, at this point, it is not considered peer-to-peer anymore.
That said, your peer doesn't even know about your TURN server, it sees your TURN generated candidates like any other candidate. Your peer still has to gather ICE candidates somehow to send you. And it can't use your TURN server to do that because you never provided its credentials throughout the workflow.
I recommend you read the book WebRTC For the Curious if you are interested in this stuff. It's very comprehensive.

Can I simplify WebRTC signalling for computers on the same private network?

WebRTC signalling is driving me crazy. My use-case is quite simple: a bidirectional audio intercom between a kiosk and to a control room webapp. Both computers are on the same network. Neither has internet access, all machines have known static IPs.
Everything I read wants me to use STUN/TURN/ICE servers. The acronyms for this is endless, contributing to my migraine but if this were a standard application, I'd just open a port, tell the other client about it (I can do this via the webapp if I need to) and have the other connect.
Can I do this with WebRTC? Without running a dozen signalling servers?
For the sake of examples, how would you connect a browser running on 192.168.0.101 to one running on 192.168.0.102?
STUN/TURN is different from signaling.
STUN/TURN in WebRTC are used to gather ICE candidates. Signaling is used to transmit between these two PCs the session description (offer and answer).
You can use free STUN server (like stun.l.google.com or stun.services.mozilla.org). There are also free TURN servers, but not too many (these are resource expensive). One is numb.vigenie.ca.
Now there's no signaling server, because these are custom and can be done in many ways. Here's an article that I wrote. I ended up using Stomp now on client side and Spring on server side.
I guess you can tamper with SDP and inject the ICE candidates statically, but you'll still need to exchange SDP (and that's dinamycally generated each session) between these two PCs somehow. Even though, taking into account that the configuration will not change, I guess you can exchange it once (through the means of copy-paste :) ), stored it somewhere and use it every time.
If your end-points have static IPs then you can ignore STUN, TURN and ICE, which are just power-tools to drill holes in firewalls. Most people aren't that lucky.
Due to how WebRTC is structured, end-points do need a way to exchange call setup information (SDP) like media ports and key information ahead of time. How you get that information from A to B and back to A, is entirely up to you ("signaling server" is just a fancy word for this), but most people use something like a web socket server, the tic-tac-toe of client-initiated communication.
I think the simplest way to make this work on a private network without an internet connection is to install a basic web socket server on one of the machines.
As an example I recommend the very simple https://github.com/emannion/webrtc-web-socket which worked on my private network without an internet connection.
Follow the instructions to install the web socket server on e.g. 192.168.1.101, then have both end-points connect to 192.168.0.101:1337 with Chrome or Firefox. Share camera on both ends in the basic demo web UI, and hit Connect and you should be good to go.
If you need to do this entirely without any server, then this answer to a related question at least highlights the information you'd need to send across (in a cut'n'paste demo).

Connect to specific user from STUN server in WEB RTC

I'm trying to achieve peer to peer video conference using google stun server.
I can connect anyone by stun server randomly.Because stun gives multiple and random addresses and connect with it.
But is there any way to connect specific peer by stun server for a login based system or room based system?
I want to achive something like - https://apprtc.appspot.com/
You need to design your signalling method (this is up to the application developer), which is independent of STUN.
WebRTC does not specify the mechanism for signalling. Signalling is the method whereby users discover each other and establish that a call (media streams between two peers) is going to take place.
The 'discovery' process could involve a registration-based system (eg using SIP proxy) or room based where two users have access to a 'room' (by knowing the credentials or some means of authentication). Once two peers have found each other, their browsers then need to share and negotiate network topology and media capabilities to ensure that the streams can reach the intended destination and can be encoded/decoded properly.

PeerConnection based on local IP's

What I want is, basically, to create a connection between two different computers on same local network. But i want to do this by computers' local IP's. (like 192.168.2.23 etc)
This must be a totally local connection. no TURN or STUN Servers. I am not sure if this is possible. Because there are not much documentation/example/information about WebRTC.
So, how can I create a connection from my computer to another one just passing its local IP as parameter?
Update: To be more clear; imagine there is an html page contains some code that activates my camera and audio services. and another -almost same- page is open in other computer. Waiting a connection request... And there is a textbox in my page to type an IP belongs to other computer on my local network. type 192.168.2.xx and bingo! i have connection between me and other computer.
I want this process as IP based, because there may be more than 2 devices on the network. And all of them are possible devices to create connection. So i need to reach them by their IP's.
Any example code or explanation would be great! even if it tells that this is not possible.
Thanks
Peer discovery is a vital part in any WebRTC application. It's an expensive term for saying: "Hi, I'm computer 4 and I want to talk to you!".
See it as calling a friend over the phone. You need to dial his number first.
This part is not defined in the WebRTC standards. You need to implement this logic in your application. Once you know who you want to call, you need a way of exchanging vital information. This is called signaling, like flo850 put in his answer.
Signaling is needed before any peer-to-peer connection can be set up.
To come up with an idea for your use case of 7 devices in a LAN.
If you have these devices connected to for example a WebSockets server and are in the same channel.
The WebSockets server can be written to route messages to specific receivers.
Devices connected to the channel often are identified with some kind of ID, imagine you use the device's IP.
When you want to talk to computer 4 with IP 192.168.0.4 you send the exchange messages (signaling) on the channel to the receiver with ID, the IP of the device you want to connect with.
How to send the signaling (offer, answer) is described here with example code.
Hope this helps
Users usually sit behind NATs; that's why ICE concept implemented in WebRTC.
If both users are sitting behind same NAT; you can skip ICE servers by passing "NULL" parameter value over "RTCPeerConnection" constructor:
var peer = new [webkit|moz]RTCPeerConnection ( null );
Now, browser will use "host" candidates, also known as "local" candidates.
you still need a signaling server. During the ICE candidate search, your clients will exchange their local ip through this signaling server

WebRTC HowTo PeerConnection via LAN with 2 Browsers

since few days I'm trying to build a basic webRTC Videochat. I've got some Demos running localy, even via LAN. But now I want to build one by my one at the really basics without so much overload some Demos come with.
But I still don't get a complete peer connection.
Eg. this example seems to be broken, because I can't "createSignalingChannel();" w3.org/TR/webrtc/#simple-example
Some other examples (https://webrtc-experiment.appspot.com/) want me to link their scripts, but I wont do this, because I want to understand the magic of the peer connection and how to get a handshake between 2 browsers.
I also explored examples with the Google App Engine but thats not what I want.
I want to run it in really easy JS and HTML just on the minimum of what is neccessary.
Here is my code:
https://github.com/mexx91/basicVideoRTC EDIT: Should work now
So what will I have to add to get an handshake and peer connection, so that I can send eg. the mediaStream to eachother.
Thanks a lot!
createSignalingChannel() is only pseudo-code to illustrate the existence of a separate channel. You need for the initial connection handling a separate message channel.
You can achieve that with hosted services like Pusher, Brightcontext or PubNub, or you can host your own backend with open-source projects like socket.io or SignalR.
Then you just need to send the offers, answers and iceCandidates through your separate channel.
List of Realtime Services: http://www.leggetter.co.uk/real-time-web-technologies-guide
Imagine a video conferencing web-app, which users A and B originally access from some webserver. Suppose that web app supports presence, so the web server knows who's currently on-line. Imahine the UI allows A to try and place a video call to B. Via say XMLHttpRequest(), A's browser informs the server this is wanted, and B's javascript pops up something saying that A wants to call B. No WebRTC has happened at all yet. But at this stage, A can indirecttly communicated with B by sending messages using e.g. XMLHttpeRequest. In WebRTC parlance, this is the "signalling channel". So, A and B can both interact with their ICE agents to discover candidate addresses, and SDP descriptions, and send these to each ot6her, via the server, over this signallinh channel. E.g. the web app on A calls a WebRTC API to get its ICE candidates, and packages these up as it sees fit, to send to B. B's reader receives this message from the server (e.g over a WebSocket or long poll) and hyence it can unpack this, and format as needed to send to the ICE agent on B, using the RTCPeerConnection object. Similalrly, SDP offer/answer can be sent betweent he two apps, and passe through into the ICE agnet in the browsers, to get agreed media formats etc. At that stage, media connections can get set uo by the browser (meida streams are added to the RTCPeerConnection initially (which aren't communicating, but whihc have attributes that can be queried to describe the codec etc, and when the API is asked to create an SDP description, it does that using these attributes, but adjust the IP address and port based on how the ICE agent on each local browser has figured out what addresses can reach that local browser / port (NAT traversal).