Hey I’m building an app that demonstrates the capabilities of webrtc. This app involves manual exchange of offer/answer. The issue I’m running into is, if the created answer is not accepted within 10 seconds in firefox browser, (15 seconds – chrome) the iceConnectionState property returns ‘failed’. However if the answer is accepted within 10 seconds, then the connection is established and iceConnectionState returns ‘connected’. Can somebody look at my code, and tell me what could be causing this behavior? Is there a bug in my code?
export default class P2P {
constructor() {
this.peerConnection;
this.dataChannel;
this.configuration = {
iceServers: [
{
urls: ['stun:stun4.l.google.com:19302']
}
],
iceCandidatePoolSize: 100
};
};
createPeerConnection = async () => {
this.peerConnection = new RTCPeerConnection(this.configuration);
this.openDataChannel();
this.peerConnection.addEventListener('connectionstatechange', (e) => {
console.log(this.peerConnection.connectionState)
});
};
openDataChannel = () => {
let options = {
reliable: true
};
this.dataChannel = this.peerConnection.createDataChannel('test', options);
this.dataChannel.binaryType = "arraybuffer";
};
getIceCandidates = () => {
return new Promise((resolve) => {
this.peerConnection.onicegatheringstatechange = () => {
if (this.peerConnection.iceGatheringState === "complete") {
console.log('ice gathering complete')
resolve();
};
};
this.peerConnection.oniceconnectionstatechange = () => {
console.log(this.peerConnection.iceConnectionState, this.peerConnection.iceGatheringState);
};
});
};
createOffer = async () => {
this.createPeerConnection();
let offer = await this.peerConnection.createOffer();
console.log("created-offer");
offer = new RTCSessionDescription(offer);
await this.peerConnection.setLocalDescription(offer);
await this.getIceCandidates();
return JSON.stringify(this.peerConnection.localDescription);
};
acceptOffer = async (offer) => {
this.createPeerConnection();
offer = new RTCSessionDescription(offer)
await this.peerConnection.setRemoteDescription(offer);
};
createAnswer = async () => {
let answer = await this.peerConnection.createAnswer();
console.log("created-answer");
answer = new RTCSessionDescription(answer);
await this.peerConnection.setLocalDescription(answer);
await this.getIceCandidates();
return JSON.stringify(this.peerConnection.localDescription);
};
acceptAnswer = async (answer) => {
if (!this.peerConnection.currentRemoteDescription) {
this.peerConnection.setRemoteDescription(answer);
console.log('accepted')
};
};
};
2
Answers
Manual exchange of offer/answer is not really a supported use-case.
WebRTC uses ICE (which stands for Interactive Connectivity Establishment) for NAT traversal and this consumes resources every second.
A ICE candidate pool size of 100 is a complete waste of resources btw.
Have you used the "perfect negotiation" logic when establishing a connection?
You may refer to the following page for detail:
https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Perfect_negotiation