implement receiving hangup, and retry on connection failure

This commit is contained in:
Bruno Windels 2022-04-12 14:02:13 +02:00
parent fd5b2aa7bb
commit 797cb23cc7
2 changed files with 37 additions and 3 deletions

View file

@ -86,6 +86,7 @@ export class PeerCall implements IDisposable {
private iceDisconnectedTimeout?: Timeout; private iceDisconnectedTimeout?: Timeout;
private _dataChannel?: any; private _dataChannel?: any;
private _hangupReason?: CallErrorCode;
constructor( constructor(
private callId: string, private callId: string,
@ -138,6 +139,8 @@ export class PeerCall implements IDisposable {
get state(): CallState { return this._state; } get state(): CallState { return this._state; }
get hangupReason(): CallErrorCode | undefined { return this._hangupReason; }
get remoteTracks(): Track[] { get remoteTracks(): Track[] {
return this.peerConnection.remoteTracks; return this.peerConnection.remoteTracks;
} }
@ -374,6 +377,17 @@ export class PeerCall implements IDisposable {
} }
} }
private handleHangupReceived(content: MCallHangupReject<MCallBase>, log: ILogItem) {
// party ID must match (our chosen partner hanging up the call) or be undefined (we haven't chosen
// a partner yet but we're treating the hangup as a reject as per VoIP v0)
// if (this.state === CallState.Ringing) {
// default reason is user_hangup
this.terminate(CallParty.Remote, content.reason || CallErrorCode.UserHangup, log);
// } else {
// log.set("ignored", true);
// }
};
private async handleFirstInvite(content: MCallInvite<MCallBase>, partyId: PartyId, log: ILogItem): Promise<void> { private async handleFirstInvite(content: MCallInvite<MCallBase>, partyId: PartyId, log: ILogItem): Promise<void> {
if (this._state !== CallState.Fledgling || this.opponentPartyId !== undefined) { if (this._state !== CallState.Fledgling || this.opponentPartyId !== undefined) {
// TODO: hangup or ignore? // TODO: hangup or ignore?
@ -789,7 +803,7 @@ export class PeerCall implements IDisposable {
} }
this.hangupParty = hangupParty; this.hangupParty = hangupParty;
// this.hangupReason = hangupReason; this._hangupReason = hangupReason;
this.setState(CallState.Ended, log); this.setState(CallState.Ended, log);
//this.localMedia?.dispose(); //this.localMedia?.dispose();
//this.localMedia = undefined; //this.localMedia = undefined;

View file

@ -16,7 +16,7 @@ limitations under the License.
import {PeerCall, CallState} from "../PeerCall"; import {PeerCall, CallState} from "../PeerCall";
import {makeTxnId, makeId} from "../../common"; import {makeTxnId, makeId} from "../../common";
import {EventType} from "../callEventTypes"; import {EventType, CallErrorCode} from "../callEventTypes";
import {formatToDeviceMessagesPayload} from "../../common"; import {formatToDeviceMessagesPayload} from "../../common";
import type {Options as PeerCallOptions} from "../PeerCall"; import type {Options as PeerCallOptions} from "../PeerCall";
@ -39,9 +39,19 @@ export type Options = Omit<PeerCallOptions, "emitUpdate" | "sendSignallingMessag
emitUpdate: (participant: Member, params?: any) => void, emitUpdate: (participant: Member, params?: any) => void,
} }
const errorCodesWithoutRetry = [
CallErrorCode.UserHangup,
CallErrorCode.AnsweredElsewhere,
CallErrorCode.Replaced,
CallErrorCode.UserBusy,
CallErrorCode.Transfered,
CallErrorCode.NewSession
];
export class Member { export class Member {
private peerCall?: PeerCall; private peerCall?: PeerCall;
private localMedia?: LocalMedia; private localMedia?: LocalMedia;
private retryCount: number = 0;
constructor( constructor(
public readonly member: RoomMember, public readonly member: RoomMember,
@ -109,6 +119,17 @@ export class Member {
if (peerCall.state === CallState.Ringing) { if (peerCall.state === CallState.Ringing) {
peerCall.answer(this.localMedia!); peerCall.answer(this.localMedia!);
} }
else if (peerCall.state === CallState.Ended) {
const hangupReason = peerCall.hangupReason;
peerCall.dispose();
this.peerCall = undefined;
if (hangupReason && !errorCodesWithoutRetry.includes(hangupReason)) {
this.retryCount += 1;
if (this.retryCount <= 3) {
this.connect(this.localMedia!);
}
}
}
this.options.emitUpdate(this, params); this.options.emitUpdate(this, params);
} }
@ -151,7 +172,6 @@ export class Member {
this.peerCall = this._createPeerCall(message.content.call_id); this.peerCall = this._createPeerCall(message.content.call_id);
} }
if (this.peerCall) { if (this.peerCall) {
const prevState = this.peerCall.state;
this.peerCall.handleIncomingSignallingMessage(message, deviceId); this.peerCall.handleIncomingSignallingMessage(message, deviceId);
} else { } else {
// TODO: need to buffer events until invite comes? // TODO: need to buffer events until invite comes?