1
Fork 0
mirror of https://github.com/jech/galene.git synced 2024-11-14 04:35:57 +01:00

Rework flushing of ICE candidates.

We now treat local and remote candidates differently, and flush
local candidates immediately after sending an offer.
This commit is contained in:
Juliusz Chroboczek 2020-12-05 02:52:56 +01:00
parent 96e5030d54
commit 9bb2499b85

View file

@ -600,7 +600,7 @@ ServerConnection.prototype.gotOffer = async function(id, labels, offer, renegoti
sc.ondownstream.call(sc, c); sc.ondownstream.call(sc, c);
await c.pc.setRemoteDescription(offer); await c.pc.setRemoteDescription(offer);
await c.flushIceCandidates(); await c.flushRemoteIceCandidates()
let answer = await c.pc.createAnswer(); let answer = await c.pc.createAnswer();
if(!answer) if(!answer)
throw new Error("Didn't create answer"); throw new Error("Didn't create answer");
@ -610,6 +610,8 @@ ServerConnection.prototype.gotOffer = async function(id, labels, offer, renegoti
id: id, id: id,
answer: answer, answer: answer,
}); });
c.localDescriptionSent = true;
c.flushLocalIceCandidates();
if(c.onnegotiationcompleted) if(c.onnegotiationcompleted)
c.onnegotiationcompleted.call(c); c.onnegotiationcompleted.call(c);
}; };
@ -648,7 +650,7 @@ ServerConnection.prototype.gotAnswer = async function(id, answer) {
c.onerror.call(c, e); c.onerror.call(c, e);
return; return;
} }
await c.flushIceCandidates(); await c.flushRemoteIceCandidates();
if(c.onnegotiationcompleted) if(c.onnegotiationcompleted)
c.onnegotiationcompleted.call(c); c.onnegotiationcompleted.call(c);
}; };
@ -779,27 +781,26 @@ function Stream(sc, id, pc) {
* @type {Object<string,string>} * @type {Object<string,string>}
*/ */
this.labelsByMid = {}; this.labelsByMid = {};
/**
* Indicates whether we have already sent a local description.
*
* @type {boolean}
*/
this.localDescriptionSent = false;
/** /**
* Buffered local ICE candidates. This will be flushed by * Buffered local ICE candidates. This will be flushed by
* flushIceCandidates when the PC becomes stable. * flushLocalIceCandidates after we send a local description.
* *
* @type {RTCIceCandidate[]} * @type {RTCIceCandidate[]}
*/ */
this.localIceCandidates = []; this.localIceCandidates = [];
/** /**
* Buffered remote ICE candidates. This will be flushed by * Buffered remote ICE candidates. This will be flushed by
* flushIceCandidates when the PC becomes stable. * flushRemoteIceCandidates when we get a remote SDP description.
* *
* @type {RTCIceCandidate[]} * @type {RTCIceCandidate[]}
*/ */
this.remoteIceCandidates = []; this.remoteIceCandidates = [];
/**
* Indicates whether it is legal to renegotiate at this point. If
* this is false, a new connection must be negotiated.
*
* @type {boolean}
*/
this.renegotiate = false;
/** /**
* The statistics last computed by the stats handler. This is * The statistics last computed by the stats handler. This is
* a dictionary indexed by track id, with each value a dictionary of * a dictionary indexed by track id, with each value a dictionary of
@ -921,7 +922,7 @@ Stream.prototype.close = function(sendclose) {
*/ */
Stream.prototype.gotLocalIce = function(candidate) { Stream.prototype.gotLocalIce = function(candidate) {
let c = this; let c = this;
if(c.pc.remoteDescription) if(c.localDescriptionSent)
c.sc.send({type: 'ice', c.sc.send({type: 'ice',
id: c.id, id: c.id,
candidate: candidate, candidate: candidate,
@ -931,13 +932,15 @@ Stream.prototype.gotLocalIce = function(candidate) {
} }
/** /**
* flushIceCandidates flushes any buffered ICE candidates. It is called * flushLocalIceCandidates flushes any buffered local ICE candidates.
* automatically when the connection reaches a stable state. * It is called when we send an offer.
* @function * @function
*/ */
Stream.prototype.flushIceCandidates = async function () { Stream.prototype.flushLocalIceCandidates = function () {
let c = this; let c = this;
c.localIceCandidates.forEach(candidate => { let candidates = c.localIceCandidates;
c.localIceCandidates = [];
candidates.forEach(candidate => {
try { try {
c.sc.send({type: 'ice', c.sc.send({type: 'ice',
id: c.id, id: c.id,
@ -947,13 +950,23 @@ Stream.prototype.flushIceCandidates = async function () {
console.warn(e); console.warn(e);
} }
}); });
c.localIceCandidates = [];
}
/**
* flushRemoteIceCandidates flushes any buffered remote ICE candidates. It is
* called automatically when we get a remote description.
* @function
*/
Stream.prototype.flushRemoteIceCandidates = async function () {
let c = this;
let candidates = c.remoteIceCandidates;
c.remoteIceCandidates = [];
/** @type {Array.<Promise<void>>} */ /** @type {Array.<Promise<void>>} */
let promises = []; let promises = [];
c.remoteIceCandidates.forEach(candidate => { candidates.forEach(candidate => {
promises.push(this.pc.addIceCandidate(candidate).catch(console.warn)); promises.push(c.pc.addIceCandidate(candidate).catch(console.warn));
}); });
c.remoteIceCandidates = [];
return await Promise.all(promises); return await Promise.all(promises);
}; };
@ -990,12 +1003,13 @@ Stream.prototype.negotiate = async function (restartIce) {
c.sc.send({ c.sc.send({
type: 'offer', type: 'offer',
kind: this.renegotiate ? 'renegotiate' : '', kind: this.localDescriptionSent ? 'renegotiate' : '',
id: c.id, id: c.id,
labels: c.labelsByMid, labels: c.labelsByMid,
offer: offer, offer: offer,
}); });
this.renegotiate = true; this.localDescriptionSent = true;
c.flushLocalIceCandidates();
}; };
/** /**