async run()

in src/task/JoinAndReceiveIndexTask.ts [37:120]


  async run(): Promise<void> {
    const indexFrame = await new Promise<SdkIndexFrame>((resolve, reject) => {
      const context = this.context;
      context.turnCredentials = null;
      class IndexFrameInterceptor implements SignalingClientObserver, TaskCanceler {
        constructor(private signalingClient: SignalingClient) {}

        cancel(): void {
          this.signalingClient.removeObserver(this);
          reject(new Error(`JoinAndReceiveIndexTask got canceled while waiting for SdkIndexFrame`));
        }

        handleSignalingClientEvent(event: SignalingClientEvent): void {
          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 = 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) {
            // @ts-ignore: force cast to SdkJoinAckFrame
            const joinAckFrame: SdkJoinAckFrame = 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): string => {
                  return context.meetingSessionConfiguration.urls.urlRewriter(uri);
                })
                .filter((uri: string) => {
                  return !!uri;
                });
            } else {
              context.logger.error('missing TURN credentials in JoinAckFrame');
            }
            return;
          }
          if (event.message.type !== SdkSignalFrame.Type.INDEX) {
            return;
          }
          this.signalingClient.removeObserver(this);
          // @ts-ignore: force cast to SdkIndexFrame
          const indexFrame: SdkIndexFrame = 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)}`);
    // We currently don't bother ingesting this into the same places as `ReceiveVideoStreamIndexTask` as we synchronously attempt a first subscribe
    // after this task completes and the state isn't quite in the right place to make it work without some refactoring. However that
    // means that we will always have an initial subscribe without any received videos.
    this.context.indexFrame = indexFrame;
  }