You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-26 17:03:12 +03:00
Better handling of send failures on VoIP events
Don't leave candidate message sin the queue, abort if we fail to send the invite.
This commit is contained in:
@@ -886,7 +886,7 @@ export class MatrixCall extends EventEmitter {
|
||||
// Now we wait for the negotiationneeded event
|
||||
};
|
||||
|
||||
private sendAnswer() {
|
||||
private async sendAnswer() {
|
||||
const answerContent = {
|
||||
answer: {
|
||||
sdp: this.peerConn.localDescription.sdp,
|
||||
@@ -908,12 +908,12 @@ export class MatrixCall extends EventEmitter {
|
||||
logger.info(`Discarding ${this.candidateSendQueue.length} candidates that will be sent in answer`);
|
||||
this.candidateSendQueue = [];
|
||||
|
||||
this.sendVoipEvent(EventType.CallAnswer, answerContent).then(() => {
|
||||
try {
|
||||
await this.sendVoipEvent(EventType.CallAnswer, answerContent);
|
||||
// If this isn't the first time we've tried to send the answer,
|
||||
// we may have candidates queued up, so send them now.
|
||||
this.inviteOrAnswerSent = true;
|
||||
this.sendCandidateQueue();
|
||||
}).catch((error) => {
|
||||
} catch (error) {
|
||||
// We've failed to answer: back to the ringing state
|
||||
this.setState(CallState.Ringing);
|
||||
this.client.cancelPendingEvent(error.event);
|
||||
@@ -926,7 +926,11 @@ export class MatrixCall extends EventEmitter {
|
||||
}
|
||||
this.emit(CallEvent.Error, new CallError(code, message, error));
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
// error handler re-throws so this won't happen on error, but
|
||||
// we don't want the same error handling on the candidate queue
|
||||
this.sendCandidateQueue();
|
||||
}
|
||||
|
||||
private gotUserMediaForAnswer = async (stream: MediaStream) => {
|
||||
@@ -1260,19 +1264,9 @@ export class MatrixCall extends EventEmitter {
|
||||
|
||||
try {
|
||||
await this.sendVoipEvent(eventType, content);
|
||||
this.sendCandidateQueue();
|
||||
if (this.state === CallState.CreateOffer) {
|
||||
this.inviteOrAnswerSent = true;
|
||||
this.setState(CallState.InviteSent);
|
||||
this.inviteTimeout = setTimeout(() => {
|
||||
this.inviteTimeout = null;
|
||||
if (this.state === CallState.InviteSent) {
|
||||
this.hangup(CallErrorCode.InviteTimeout, false);
|
||||
}
|
||||
}, CALL_TIMEOUT_MS);
|
||||
}
|
||||
} catch (error) {
|
||||
this.client.cancelPendingEvent(error.event);
|
||||
logger.error("Failed to send invite", error);
|
||||
if (error.event) this.client.cancelPendingEvent(error.event);
|
||||
|
||||
let code = CallErrorCode.SignallingFailed;
|
||||
let message = "Signalling failed";
|
||||
@@ -1287,6 +1281,22 @@ export class MatrixCall extends EventEmitter {
|
||||
|
||||
this.emit(CallEvent.Error, new CallError(code, message, error));
|
||||
this.terminate(CallParty.Local, code, false);
|
||||
|
||||
// no need to carry on & send the candidate queue, but we also
|
||||
// don't want to rethrow the error
|
||||
return;
|
||||
}
|
||||
|
||||
this.sendCandidateQueue();
|
||||
if (this.state === CallState.CreateOffer) {
|
||||
this.inviteOrAnswerSent = true;
|
||||
this.setState(CallState.InviteSent);
|
||||
this.inviteTimeout = setTimeout(() => {
|
||||
this.inviteTimeout = null;
|
||||
if (this.state === CallState.InviteSent) {
|
||||
this.hangup(CallErrorCode.InviteTimeout, false);
|
||||
}
|
||||
}, CALL_TIMEOUT_MS);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1623,7 +1633,7 @@ export class MatrixCall extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
private sendCandidateQueue() {
|
||||
private async sendCandidateQueue() {
|
||||
if (this.candidateSendQueue.length === 0) {
|
||||
return;
|
||||
}
|
||||
@@ -1635,20 +1645,28 @@ export class MatrixCall extends EventEmitter {
|
||||
candidates: cands,
|
||||
};
|
||||
logger.debug("Attempting to send " + cands.length + " candidates");
|
||||
this.sendVoipEvent(EventType.CallCandidates, content).then(() => {
|
||||
this.candidateSendTries = 0;
|
||||
this.sendCandidateQueue();
|
||||
}, (error) => {
|
||||
for (let i = 0; i < cands.length; i++) {
|
||||
this.candidateSendQueue.push(cands[i]);
|
||||
}
|
||||
try {
|
||||
await this.sendVoipEvent(EventType.CallCandidates, content);
|
||||
} catch (error) {
|
||||
// don't retry this event: we'll send another one later as we might
|
||||
// have more candidates by then.
|
||||
if (error.event) this.client.cancelPendingEvent(error.event);
|
||||
|
||||
// put all the candidates we failed to send back in the queue
|
||||
this.candidateSendQueue.push(...cands);
|
||||
|
||||
if (this.candidateSendTries > 5) {
|
||||
logger.debug(
|
||||
"Failed to send candidates on attempt " + this.candidateSendTries +
|
||||
". Giving up for now.", error,
|
||||
". Giving up on this call.", error,
|
||||
);
|
||||
this.candidateSendTries = 0;
|
||||
|
||||
const code = CallErrorCode.SignallingFailed;
|
||||
const message = "Signalling failed";
|
||||
|
||||
this.emit(CallEvent.Error, new CallError(code, message, error));
|
||||
this.hangup(code, false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1658,7 +1676,7 @@ export class MatrixCall extends EventEmitter {
|
||||
setTimeout(() => {
|
||||
this.sendCandidateQueue();
|
||||
}, delayMs);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async placeCallWithConstraints(constraints: MediaStreamConstraints) {
|
||||
|
||||
Reference in New Issue
Block a user