fetch turn server settings when joining a call, and pass down

This commit is contained in:
Bruno Windels 2022-09-26 15:25:24 +02:00
parent 035ead0d5b
commit 3a4c38086c
4 changed files with 35 additions and 17 deletions

View File

@ -23,6 +23,7 @@ import {GroupCall} from "./group/GroupCall";
import {makeId} from "../common";
import {CALL_LOG_TYPE} from "./common";
import {EVENT_TYPE as MEMBER_EVENT_TYPE, RoomMember} from "../room/members/RoomMember";
import {TurnServerSource} from "./TurnServerSource";
import type {LocalMedia} from "./LocalMedia";
import type {Room} from "../room/Room";
@ -57,6 +58,7 @@ export class CallHandler implements RoomStateHandler {
constructor(private readonly options: Options) {
this.groupCallOptions = Object.assign({}, this.options, {
turnServerSource: new TurnServerSource(this.options.hsApi, this.options.clock),
emitUpdate: (groupCall, params) => this._calls.update(groupCall.id, params),
createTimeout: this.options.clock.createTimeout,
sessionId: this.sessionId
@ -75,12 +77,6 @@ export class CallHandler implements RoomStateHandler {
this._loadCallEntries(callEntries, txn);
}
setTurnServers(turnServers: RTCIceServer[]) {
this.options.turnServers = turnServers;
this.groupCallOptions.turnServers = turnServers;
// TODO: we should update any ongoing peerconnections if the TURN server details have changed
}
private async _getLoadTxn(): Promise<Transaction> {
const names = this.options.storage.storeNames;
const txn = await this.options.storage.readTxn([

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
import {ObservableMap} from "../../observable/map/ObservableMap";
import {BaseObservableValue} from "../../observable/value/BaseObservableValue";
import {recursivelyAssign} from "../../utils/recursivelyAssign";
import {Disposables, Disposable, IDisposable} from "../../utils/Disposables";
import {WebRTC, PeerConnection, Transceiver, TransceiverDirection, Sender, Receiver, PeerConnectionEventMap} from "../../platform/types/WebRTC";
@ -47,7 +48,7 @@ import type {
export type Options = {
webRTC: WebRTC,
forceTURN: boolean,
turnServers: RTCIceServer[],
turnServer: BaseObservableValue<RTCIceServer>,
createTimeout: TimeoutCreator,
emitUpdate: (peerCall: PeerCall, params: any, log: ILogItem) => void;
sendSignallingMessage: (message: SignallingMessage<MCallBase>, log: ILogItem) => Promise<void>;

View File

@ -23,6 +23,7 @@ import {EventEmitter} from "../../../utils/EventEmitter";
import {EventType, CallIntent} from "../callEventTypes";
import type {Options as MemberOptions} from "./Member";
import type {TurnServerSource} from "../TurnServerSource";
import type {BaseObservableMap} from "../../../observable/map/BaseObservableMap";
import type {Track} from "../../../platform/types/MediaDevices";
import type {SignallingMessage, MGroupCallBase, CallMembership} from "../callEventTypes";
@ -32,6 +33,7 @@ import type {Platform} from "../../../platform/web/Platform";
import type {EncryptedMessage} from "../../e2ee/olm/Encryption";
import type {ILogItem, ILogger} from "../../../logging/types";
import type {Storage} from "../../storage/idb/Storage";
import type {BaseObservableValue} from "../../../observable/value/BaseObservableValue";
export enum GroupCallState {
Fledgling = "fledgling",
@ -53,11 +55,12 @@ function getDeviceFromMemberKey(key: string): string {
return JSON.parse(`[${key}]`)[1];
}
export type Options = Omit<MemberOptions, "emitUpdate" | "confId" | "encryptDeviceMessage"> & {
export type Options = Omit<MemberOptions, "emitUpdate" | "confId" | "encryptDeviceMessage" | "turnServer"> & {
emitUpdate: (call: GroupCall, params?: any) => void;
encryptDeviceMessage: (roomId: string, userId: string, deviceId: string, message: SignallingMessage<MGroupCallBase>, log: ILogItem) => Promise<EncryptedMessage | undefined>,
storage: Storage,
logger: ILogger,
turnServerSource: TurnServerSource
};
class JoinedData {
@ -65,7 +68,8 @@ class JoinedData {
public readonly logItem: ILogItem,
public readonly membersLogItem: ILogItem,
public localMedia: LocalMedia,
public localMuteSettings: MuteSettings
public localMuteSettings: MuteSettings,
public turnServer: BaseObservableValue<RTCIceServer>
) {}
dispose() {
@ -136,6 +140,7 @@ export class GroupCall extends EventEmitter<{change: never}> {
id: this.id,
ownSessionId: this.options.sessionId
});
const turnServer = await this.options.turnServerSource.getSettings(logItem);
const membersLogItem = logItem.child("member connections");
const localMuteSettings = new MuteSettings();
localMuteSettings.updateTrackInfo(localMedia.userMedia);
@ -143,7 +148,8 @@ export class GroupCall extends EventEmitter<{change: never}> {
logItem,
membersLogItem,
localMedia,
localMuteSettings
localMuteSettings,
turnServer
);
this.joinedData = joinedData;
await joinedData.logItem.wrap("join", async log => {
@ -509,7 +515,12 @@ export class GroupCall extends EventEmitter<{change: never}> {
const logItem = joinedData.membersLogItem.child({l: "member", id: memberKey});
logItem.set("sessionId", member.sessionId);
log.wrap({l: "connect", id: memberKey}, log => {
const connectItem = member.connect(joinedData.localMedia, joinedData.localMuteSettings, logItem);
const connectItem = member.connect(
joinedData.localMedia,
joinedData.localMuteSettings,
joinedData.turnServer,
logItem
);
if (connectItem) {
log.refDetached(connectItem);
}

View File

@ -19,6 +19,7 @@ import {makeTxnId, makeId} from "../../common";
import {EventType, CallErrorCode} from "../callEventTypes";
import {formatToDeviceMessagesPayload} from "../../common";
import {sortedIndex} from "../../../utils/sortedIndex";
import type {MuteSettings} from "../common";
import type {Options as PeerCallOptions, RemoteMedia} from "../PeerCall";
import type {LocalMedia} from "../LocalMedia";
@ -28,8 +29,9 @@ import type {GroupCall} from "./GroupCall";
import type {RoomMember} from "../../room/members/RoomMember";
import type {EncryptedMessage} from "../../e2ee/olm/Encryption";
import type {ILogItem} from "../../../logging/types";
import type {BaseObservableValue} from "../../../observable/value/BaseObservableValue";
export type Options = Omit<PeerCallOptions, "emitUpdate" | "sendSignallingMessage"> & {
export type Options = Omit<PeerCallOptions, "emitUpdate" | "sendSignallingMessage" | "turnServer"> & {
confId: string,
ownUserId: string,
ownDeviceId: string,
@ -60,6 +62,7 @@ class MemberConnection {
constructor(
public localMedia: LocalMedia,
public localMuteSettings: MuteSettings,
public turnServer: BaseObservableValue<RTCIceServer>,
public readonly logItem: ILogItem
) {}
}
@ -112,12 +115,17 @@ export class Member {
}
/** @internal */
connect(localMedia: LocalMedia, localMuteSettings: MuteSettings, memberLogItem: ILogItem): ILogItem | undefined {
connect(localMedia: LocalMedia, localMuteSettings: MuteSettings, turnServer: BaseObservableValue<RTCIceServer>, memberLogItem: ILogItem): ILogItem | undefined {
if (this.connection) {
return;
}
// Safari can't send a MediaStream to multiple sources, so clone it
const connection = new MemberConnection(localMedia.clone(), localMuteSettings, memberLogItem);
const connection = new MemberConnection(
localMedia.clone(),
localMuteSettings,
turnServer,
memberLogItem
);
this.connection = connection;
let connectLogItem;
connection.logItem.wrap("connect", async log => {
@ -204,7 +212,7 @@ export class Member {
if (hangupReason && !errorCodesWithoutRetry.includes(hangupReason)) {
connection.retryCount += 1;
const {retryCount} = connection;
connection.logItem.wrap({l: "retry connection", retryCount}, async retryLog => {
connection.logItem.wrap({l: "retry connection", retryCount}, async retryLog => {
log.refDetached(retryLog);
if (retryCount <= 3) {
await this.callIfNeeded(retryLog);
@ -337,9 +345,11 @@ export class Member {
}
private _createPeerCall(callId: string): PeerCall {
const connection = this.connection!;
return new PeerCall(callId, Object.assign({}, this.options, {
emitUpdate: this.emitUpdateFromPeerCall,
sendSignallingMessage: this.sendSignallingMessage
}), this.connection!.logItem);
sendSignallingMessage: this.sendSignallingMessage,
turnServer: connection.turnServer
}), connection.logItem);
}
}