forked from mystiq/hydrogen-web
WIP8
This commit is contained in:
parent
98b77fc761
commit
25b0148073
2 changed files with 23 additions and 15 deletions
|
@ -21,6 +21,7 @@ import type {Room} from "../room/Room";
|
||||||
import type {StateEvent} from "../storage/types";
|
import type {StateEvent} from "../storage/types";
|
||||||
import type {ILogItem} from "../../logging/types";
|
import type {ILogItem} from "../../logging/types";
|
||||||
|
|
||||||
|
import type {TimeoutCreator, Timeout} from "../../platform/types/types";
|
||||||
import {WebRTC, PeerConnection, PeerConnectionHandler} from "../../platform/types/WebRTC";
|
import {WebRTC, PeerConnection, PeerConnectionHandler} from "../../platform/types/WebRTC";
|
||||||
import {MediaDevices, Track, AudioTrack, TrackType} from "../../platform/types/MediaDevices";
|
import {MediaDevices, Track, AudioTrack, TrackType} from "../../platform/types/MediaDevices";
|
||||||
import type {LocalMedia} from "./LocalMedia";
|
import type {LocalMedia} from "./LocalMedia";
|
||||||
|
@ -49,10 +50,12 @@ class PeerCall {
|
||||||
private responsePromiseChain?: Promise<void>;
|
private responsePromiseChain?: Promise<void>;
|
||||||
private opponentPartyId?: PartyId;
|
private opponentPartyId?: PartyId;
|
||||||
private hangupParty: CallParty;
|
private hangupParty: CallParty;
|
||||||
|
private hangupTimeout?: Timeout;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly handler: PeerCallHandler,
|
private readonly handler: PeerCallHandler,
|
||||||
private localMedia: LocalMedia,
|
private localMedia: LocalMedia,
|
||||||
|
private readonly createTimeout: TimeoutCreator,
|
||||||
webRTC: WebRTC
|
webRTC: WebRTC
|
||||||
) {
|
) {
|
||||||
const outer = this;
|
const outer = this;
|
||||||
|
@ -84,7 +87,7 @@ class PeerCall {
|
||||||
this.handleInvite(message.content, partyId);
|
this.handleInvite(message.content, partyId);
|
||||||
break;
|
break;
|
||||||
case EventType.Answer:
|
case EventType.Answer:
|
||||||
this.handleAnswer(message.content);
|
this.handleAnswer(message.content, partyId);
|
||||||
break;
|
break;
|
||||||
case EventType.Candidates:
|
case EventType.Candidates:
|
||||||
this.handleRemoteIceCandidates(message.content);
|
this.handleRemoteIceCandidates(message.content);
|
||||||
|
@ -148,9 +151,7 @@ class PeerCall {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Allow a short time for initial candidates to be gathered
|
// Allow a short time for initial candidates to be gathered
|
||||||
await new Promise(resolve => {
|
await this.createTimeout(200).elapsed();
|
||||||
setTimeout(resolve, 200);
|
|
||||||
});
|
|
||||||
this.sendAnswer();
|
this.sendAnswer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +181,7 @@ class PeerCall {
|
||||||
applyTrack(m => m.screenShareTrack);
|
applyTrack(m => m.screenShareTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calls are serialized and deduplicated by negotiationQueue
|
// calls are serialized and deduplicated by responsePromiseChain
|
||||||
private handleNegotiation = async (): Promise<void> => {
|
private handleNegotiation = async (): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
await this.peerConnection.setLocalDescription();
|
await this.peerConnection.setLocalDescription();
|
||||||
|
@ -192,7 +193,7 @@ class PeerCall {
|
||||||
|
|
||||||
if (this.peerConnection.iceGatheringState === 'gathering') {
|
if (this.peerConnection.iceGatheringState === 'gathering') {
|
||||||
// Allow a short time for initial candidates to be gathered
|
// Allow a short time for initial candidates to be gathered
|
||||||
await new Promise(resolve => setTimeout(resolve, 200));
|
await this.createTimeout(200).elapsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state === CallState.Ended) {
|
if (this.state === CallState.Ended) {
|
||||||
|
@ -220,12 +221,12 @@ class PeerCall {
|
||||||
this.sendCandidateQueue();
|
this.sendCandidateQueue();
|
||||||
|
|
||||||
if (this.state === CallState.CreateOffer) {
|
if (this.state === CallState.CreateOffer) {
|
||||||
this.inviteTimeout = setTimeout(() => {
|
this.hangupTimeout = this.createTimeout(CALL_TIMEOUT_MS);
|
||||||
this.inviteTimeout = null;
|
await this.hangupTimeout.elapsed();
|
||||||
|
// @ts-ignore TS doesn't take the await above into account to know that the state could have changed in between
|
||||||
if (this.state === CallState.InviteSent) {
|
if (this.state === CallState.InviteSent) {
|
||||||
this.hangup(CallErrorCode.InviteTimeout);
|
this.hangup(CallErrorCode.InviteTimeout);
|
||||||
}
|
}
|
||||||
}, CALL_TIMEOUT_MS);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -333,10 +334,9 @@ class PeerCall {
|
||||||
// MSC2746 recommends these values (can be quite long when calling because the
|
// MSC2746 recommends these values (can be quite long when calling because the
|
||||||
// callee will need a while to answer the call)
|
// callee will need a while to answer the call)
|
||||||
const delay = this.direction === CallDirection.Inbound ? 500 : 2000;
|
const delay = this.direction === CallDirection.Inbound ? 500 : 2000;
|
||||||
|
this.createTimeout(delay).elapsed().then(() => {
|
||||||
setTimeout(() => {
|
|
||||||
this.sendCandidateQueue();
|
this.sendCandidateQueue();
|
||||||
}, delay);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,3 +43,11 @@ export type File = {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly blob: IBlobHandle;
|
readonly blob: IBlobHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Timeout {
|
||||||
|
elapsed(): Promise<void>;
|
||||||
|
abort(): void;
|
||||||
|
dispose(): void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TimeoutCreator = (timeout: number) => Timeout;
|
||||||
|
|
Loading…
Reference in a new issue