blob: 9161966a78ae2be0b4345472066d24d48c662872 [file] [log] [blame]
'use strict';
/**
* A WebRTC peer connection helper. Tightly coupled with the signaling
* class.
*/
class WebRTCPeerConnection {
constructor(signaling, offering, configuration = null) {
// Set default configuration (if none provided)
if (configuration === null) {
configuration = {
iceServers: [{
urls: 'stun:stun.services.mozilla.com',
}],
};
}
// Create peer connection and bind events
const pc = new RTCPeerConnection(configuration);
pc._offering = offering; // Meh!
signaling.pc = pc;
pc.onnegotiationneeded = async () => {
console.log('Negotiation needed');
// Create offer (if required)
if (offering) {
console.log('Creating offer');
const description = await pc.createOffer();
await pc.setLocalDescription(description);
signaling.handleLocalDescription(description);
}
};
pc.signalingstatechange = () => {
console.log('Signaling state:', pc.signalingState);
};
pc.oniceconnectionstatechange = () => {
console.log('ICE connection state:', pc.iceConnectionState);
};
pc.onicegatheringstatechange = () => {
console.log('ICE gathering state:', pc.iceGatheringState);
};
pc.onconnectionstatechange = () => {
console.log('Connection state:', pc.connectionState);
};
pc.onicecandidate = (event) => {
signaling.handleLocalCandidate(event.candidate);
};
pc.onicecandidateerror = (event) => {
console.error('ICE candidate error:', event);
};
pc.ondatachannel = (event) => {
const dc = event.channel;
console.log('Incoming data channel:', dc.label);
// Bind events
this.bindDataChannelEvents(dc);
};
// Store configuration & signalling instance
this.pc = pc;
this.dcs = {};
}
createDataChannel(name, options = null) {
const pc = this.pc;
// Create data channel and bind events
const dc = pc.createDataChannel(name, options);
this.bindDataChannelEvents(dc);
// Store data channel and return
this.dcs[name] = dc;
return dc;
}
bindDataChannelEvents(dc) {
dc._name = dc.label; // Meh!
dc.onopen = () => {
console.log(dc._name, 'open');
};
dc.onclose = () => {
console.log(dc._name, 'closed');
};
dc.onerror = (event) => {
console.log(dc._name, 'error:', event);
};
dc.onbufferedamountlow = () => {
console.log(dc._name, 'buffered amount low:', dc.bufferedAmount);
};
dc.onmessage = (event) => {
const size = event.data.byteLength || event.data.size;
console.log(dc._name, 'incoming message (' + size + ' bytes)');
};
}
}