Created
July 14, 2019 21:00
-
-
Save menduz/217d183901f7cad00b9163ce7ad5df68 to your computer and use it in GitHub Desktop.
WebRTC basic setup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This configuration is passed when we create a new peer connection object. | |
// It provides a set of servers used to establish a connection. STUN servers | |
// are used to discover our external IP address, and TURN servers (none listed | |
// here) are used to proxy a connection when a peer is behind a restrictive | |
// firewall that prevents a direct connection. | |
var peerConnectionConfig = { | |
iceServers: [ | |
{ urls: "stun:stun.l.google.com:19302" }, | |
{ urls: "stun:stun1.l.google.com:19302" }, | |
{ urls: "stun:stun2.l.google.com:19302" }, | |
{ urls: "stun:stun3.l.google.com:19302" }, | |
{ urls: "stun:stun4.l.google.com:19302" } | |
] | |
}; | |
// Think of offerPeer as our local client. It's going to create a data channel | |
// and an offer and send them to the other peer. | |
var offerPeer = new RTCPeerConnection(peerConnectionConfig); | |
offerPeer.onicecandidate = onOfferPeerIceCandidate; | |
// Think of answerPeer as our remote server. It's going to accept an offer | |
// from offerPeer, and create a corresponding answer. | |
var answerPeer = new RTCPeerConnection(peerConnectionConfig); | |
answerPeer.ondatachannel = dc => { | |
console.log("answer data channel created", dc.channel); | |
addDataChannelListeners(dc.channel, "answerPeer"); | |
dc.channel.addEventListener("open", () => { | |
dc.channel.send("hellown"); | |
}); | |
}; | |
answerPeer.onicecandidate = evt => { | |
console.log("got answer candidate", evt); | |
if (evt.candidate) { | |
offerPeer.addIceCandidate(evt.candidate); | |
} | |
}; | |
// Create the offered data channel. Note that this must happen before the | |
// offer is created, so that it is included in the offer. | |
var offerDataChannel = offerPeer.createDataChannel("dataChannel", {}); | |
addDataChannelListeners(offerDataChannel, "offerPeer"); | |
// Create an offer to send to answerPeer. Like most operations with the WebRTC | |
// API, this is asynchronous. Our callback will be invoked once an offer has | |
// been created. | |
offerPeer | |
.createOffer({}) | |
.then(async offer => { | |
console.log("got offer", offer); | |
const newOffer = new RTCSessionDescription(offer); | |
console.log("newOffer", newOffer); | |
await offerPeer.setLocalDescription(newOffer); | |
// Normally we would send this over the wire to answerPeer, but since this is | |
// all local, we can just set it here. | |
await answerPeer.setRemoteDescription(newOffer); | |
const answer = await answerPeer.createAnswer(); | |
console.log("got answer", answer); | |
const newAnswer = new RTCSessionDescription(answer); | |
console.log("newAnswer", newAnswer); | |
await answerPeer.setLocalDescription(newAnswer); | |
// Normally we would send this over the wire to offerPeer, but since this is | |
// all local, we can just set it here. | |
await offerPeer.setRemoteDescription(newAnswer); | |
}) | |
.catch($ => console.error($)); | |
// This is used to attach generic logging handlers for data channels. | |
function addDataChannelListeners(channel: RTCDataChannel, label: string) { | |
channel.onclose = function(event) { | |
console.log(label + " data channel close", event); | |
}; | |
channel.onerror = function(err) { | |
console.log(label + " data channel error", event); | |
}; | |
channel.onmessage = function(event) { | |
console.log(label + " data channel message", event); | |
}; | |
channel.onopen = function(event) { | |
console.log(label + " data channel open", event); | |
channel.send("hello from " + label); | |
}; | |
} | |
// This will be called for each offer candidate. A candidate is a potential | |
// address that the other peer can attempt to connect to. Note that | |
// event.candidate can be null, so we must guard against that. The two peers | |
// will exchange candidates until they find a connection that works. | |
function onOfferPeerIceCandidate(event: RTCPeerConnectionIceEvent) { | |
if (event && event.candidate) { | |
// These would normally be sent to answerPeer over some other transport, | |
// like a websocket, but since this is local we can just set it here. | |
answerPeer.addIceCandidate(event.candidate); | |
} | |
} | |
console.log("Initializing rtc"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment