import AudioVideoControllerState from '../audiovideocontroller/AudioVideoControllerState' ; import MeetingSessionStatus from '../meetingsession/MeetingSessionStatus' ; import MeetingSessionStatusCode from '../meetingsession/MeetingSessionStatusCode' ; import MeetingSessionTURNCredentials from '../meetingsession/MeetingSessionTURNCredentials' ; import SignalingClient from '../signalingclient/SignalingClient' ; import SignalingClientEvent from '../signalingclient/SignalingClientEvent' ; import SignalingClientEventType from '../signalingclient/SignalingClientEventType' ; import SignalingClientJoin from '../signalingclient/SignalingClientJoin' ; import SignalingClientObserver from '../signalingclientobserver/SignalingClientObserver' ; import { SdkIndexFrame , SdkSignalFrame } from '../signalingprotocol/SignalingProtocol.js' ; import TaskCanceler from '../taskcanceler/TaskCanceler' ; import BaseTask from './BaseTask' ; export default class JoinAndReceiveIndexTask extends BaseTask { protected taskName = 'JoinAndReceiveIndexTask' ; private taskCanceler : TaskCanceler | null = null ; private maxVideos = 25 ; constructor ( private context ) { super ( context . logger ) ; } cancel ( ) { if ( this . taskCanceler ) { this . taskCanceler . cancel ( ) ; this . taskCanceler = null ; } } async run ( ) { const indexFrame = await new Promise < SdkIndexFrame > ( ( resolve , reject ) => { const context = this . context ; context . turnCredentials = null ; class IndexFrameInterceptor implements SignalingClientObserver , TaskCanceler { constructor ( private signalingClient ) { } cancel ( ) { this . signalingClient . removeObserver ( this ) ; reject ( new Error ( `JoinAndReceiveIndexTask got canceled while waiting for SdkIndexFrame` ) ) ; } handleSignalingClientEvent ( event ) { if ( event . type === SignalingClientEventType . WebSocketClosed ) { let message = `The signaling connection was closed with code ${ event . closeCode } and reason: ${ event . closeReason }` ; context . logger . warn ( message ) ; let statusCode = MeetingSessionStatusCode . SignalingBadRequest ; if ( event . closeCode === 4410 ) { message = 'The meeting already ended.' ; context . logger . warn ( message ) ; statusCode = MeetingSessionStatusCode . MeetingEnded ; } else if ( event . closeCode >= 4500 && event . closeCode < 4600 ) { statusCode = MeetingSessionStatusCode . SignalingInternalServerError ; } context . audioVideoController . handleMeetingSessionStatus ( new MeetingSessionStatus ( statusCode ) , new Error ( message ) ) ; return ; } if ( event . type !== SignalingClientEventType . ReceivedSignalFrame ) { return ; } if ( event . message . type === SdkSignalFrame . Type . JOIN_ACK ) { const joinAckFrame = event . message . joinack ; if ( joinAckFrame && joinAckFrame . videoSubscriptionLimit ) { context . videoSubscriptionLimit = joinAckFrame . videoSubscriptionLimit ; } if ( joinAckFrame && joinAckFrame . turnCredentials ) { context . turnCredentials = new MeetingSessionTURNCredentials ( ) ; context . turnCredentials . username = joinAckFrame . turnCredentials . username ; context . turnCredentials . password = joinAckFrame . turnCredentials . password ; context . turnCredentials . ttl = joinAckFrame . turnCredentials . ttl ; context . turnCredentials . uris = joinAckFrame . turnCredentials . uris . map ( ( uri ) : string => { return context . meetingSessionConfiguration . urls . urlRewriter ( uri ) ; } ) . filter ( ( uri ) => { return ! ! uri ; } ) ; } else { context . logger . error ( 'missing TURN credentials in JoinAckFrame' ) ; } return ; } if ( event . message . type !== SdkSignalFrame . Type . INDEX ) { return ; } this . signalingClient . removeObserver ( this ) ; const indexFrame = event . message . index ; resolve ( indexFrame ) ; } } const interceptor = new IndexFrameInterceptor ( this . context . signalingClient ) ; this . context . signalingClient . registerObserver ( interceptor ) ; this . taskCanceler = interceptor ; this . context . signalingClient . join ( new SignalingClientJoin ( this . maxVideos , true , this . context . meetingSessionConfiguration . applicationMetadata ) ) ; } ) ; this . context . logger . info ( `received first index ${ JSON . stringify ( indexFrame ) }` ) ; this . context . indexFrame = indexFrame ; } }