1
Fork 0
mirror of https://github.com/jech/galene.git synced 2024-11-23 00:55:58 +01:00

Buffer local ICE candidates.

Apparently, it is possible for an ICE candidate to be generated
before onnegotiationneeded triggers.  Avoid losing a candidate
in that case.
This commit is contained in:
Juliusz Chroboczek 2020-10-30 00:16:09 +01:00
parent 56641b8d84
commit 4911b7ad38

View file

@ -269,7 +269,7 @@ ServerConnection.prototype.connect = async function(url) {
sc.gotAbort(m.id); sc.gotAbort(m.id);
break; break;
case 'ice': case 'ice':
sc.gotICE(m.id, m.candidate); sc.gotRemoteIce(m.id, m.candidate);
break; break;
case 'label': case 'label':
sc.gotLabel(m.id, m.value); sc.gotLabel(m.id, m.value);
@ -403,10 +403,7 @@ ServerConnection.prototype.newUpStream = function(id) {
pc.onicecandidate = e => { pc.onicecandidate = e => {
if(!e.candidate) if(!e.candidate)
return; return;
sc.send({type: 'ice', c.gotLocalIce(e.candidate);
id: id,
candidate: e.candidate,
});
}; };
pc.oniceconnectionstatechange = e => { pc.oniceconnectionstatechange = e => {
@ -502,10 +499,7 @@ ServerConnection.prototype.gotOffer = async function(id, labels, offer, renegoti
c.pc.onicecandidate = function(e) { c.pc.onicecandidate = function(e) {
if(!e.candidate) if(!e.candidate)
return; return;
sc.send({type: 'ice', c.gotLocalIce(e.candidate);
id: id,
candidate: e.candidate,
});
}; };
pc.oniceconnectionstatechange = e => { pc.oniceconnectionstatechange = e => {
@ -650,7 +644,7 @@ ServerConnection.prototype.gotAbort = function(id) {
* @param {RTCIceCandidate} candidate * @param {RTCIceCandidate} candidate
* @function * @function
*/ */
ServerConnection.prototype.gotICE = async function(id, candidate) { ServerConnection.prototype.gotRemoteIce = async function(id, candidate) {
let c = this.up[id]; let c = this.up[id];
if(!c) if(!c)
c = this.down[id]; c = this.down[id];
@ -659,7 +653,7 @@ ServerConnection.prototype.gotICE = async function(id, candidate) {
if(c.pc.remoteDescription) if(c.pc.remoteDescription)
await c.pc.addIceCandidate(candidate).catch(console.warn); await c.pc.addIceCandidate(candidate).catch(console.warn);
else else
c.iceCandidates.push(candidate); c.remoteIceCandidates.push(candidate);
}; };
/** /**
@ -728,12 +722,19 @@ function Stream(sc, id, pc) {
*/ */
this.labelsByMid = {}; this.labelsByMid = {};
/** /**
* Buffered ICE candidates. This will be flushed by flushIceCandidates * Buffered local ICE candidates. This will be flushed by
* when the PC becomes stable. * flushIceCandidates when the PC becomes stable.
* *
* @type {RTCIceCandidate[]} * @type {RTCIceCandidate[]}
*/ */
this.iceCandidates = []; this.localIceCandidates = [];
/**
* Buffered remote ICE candidates. This will be flushed by
* flushIceCandidates when the PC becomes stable.
*
* @type {RTCIceCandidate[]}
*/
this.remoteIceCandidates = [];
/** /**
* Indicates whether it is legal to renegotiate at this point. If * Indicates whether it is legal to renegotiate at this point. If
* this is false, a new connection must be negotiated. * this is false, a new connection must be negotiated.
@ -853,18 +854,47 @@ Stream.prototype.close = function(sendclose) {
c.sc = null; c.sc = null;
}; };
/**
* Called when we get a local ICE candidate. Don't call this.
*
* @param {RTCIceCandidate} candidate
* @function
*/
Stream.prototype.gotLocalIce = function(candidate) {
let c = this;
if(c.pc.remoteDescription)
c.sc.send({type: 'ice',
id: c.id,
candidate: candidate,
});
else
c.localIceCandidates.push(candidate);
}
/** /**
* flushIceCandidates flushes any buffered ICE candidates. It is called * flushIceCandidates flushes any buffered ICE candidates. It is called
* automatically when the connection reaches a stable state. * automatically when the connection reaches a stable state.
* @function * @function
*/ */
Stream.prototype.flushIceCandidates = async function () { Stream.prototype.flushIceCandidates = async function () {
let c = this;
c.localIceCandidates.forEach(candidate => {
try {
c.sc.send({type: 'ice',
id: c.id,
candidate: candidate,
});
} catch(e) {
console.warn(e);
}
});
/** @type {Promise<void>[]} */ /** @type {Promise<void>[]} */
let promises = []; let promises = [];
this.iceCandidates.forEach(c => { c.remoteIceCandidates.forEach(candidate => {
promises.push(this.pc.addIceCandidate(c).catch(console.warn)); promises.push(this.pc.addIceCandidate(candidate).catch(console.warn));
}); });
this.iceCandidates = []; c.remoteIceCandidates = [];
return await Promise.all(promises); return await Promise.all(promises);
}; };