establishConnection method

  1. @override
void establishConnection({
  1. bool forceConnection = false,
  2. int numberOfRetries = 3,
  3. String? forceAccessToken,
  4. Function? callbackConnected,
})
override

Implementation

@override
void establishConnection({
  bool forceConnection = false,
  int numberOfRetries = 3,
  String? forceAccessToken,
  Function? callbackConnected,
}) {
  if (_authLocal.accessToken.isEmpty ||
      (_socket != null && !forceConnection)) {
    return;
  }

  disconnection();

  final String mAccessToken = forceAccessToken ?? _authLocal.accessToken;

  _socket = io(
    WaterbusSdk.wsUrl,
    OptionBuilder()
        .setTransports(kIsWeb ? ['polling'] : ['websocket'])
        .enableReconnection()
        .enableForceNew()
        .setExtraHeaders({
      'Authorization': 'Bearer $mAccessToken',
    }).build(),
  );

  _socket?.connect();

  _socket?.onError((data) async {
    if (_authLocal.accessToken.isEmpty || numberOfRetries == 0) return;

    final (String newAccessToken, _) = await _dioConfig.onRefreshToken(
      oldAccessToken: mAccessToken,
    );

    Future.delayed(1.seconds, () {
      establishConnection(
        forceConnection: true,
        forceAccessToken: newAccessToken,
        numberOfRetries: numberOfRetries - 1,
      );
    });
  });

  _socket?.onConnect((_) async {
    callbackConnected?.call();

    _logger.log('established connection - sid: ${_socket?.id}');

    _socket?.on(SocketEvent.publishSSC, (data) {
      /// pc context: only send peer
      /// will receive sdp remote from service side if you join success
      /// otherParticipants, sdp (data)

      if (data == null) return;

      final String sdp = data['sdp'];
      final bool isRecording = data['isRecording'];

      _rtcManager.setPublisherRemoteSdp(sdp, isRecording);
    });

    _socket?.on(SocketEvent.newParticipantSSC, (data) {
      /// Will receive signal when someone join,
      /// targetId
      if (data == null) return;

      final participant = Participant.fromMap(data);

      _rtcManager.newParticipant(participant);
    });

    _socket?.on(SocketEvent.answerSubscriberSSC, (data) async {
      /// pc context: only receive peer
      /// will receive sdp, get it and add to pc
      /// sdp, targetId
      if (data == null || data['offer'] == null) return;

      final WebRTCCodec codec =
          ((data['videoCodec'] ?? '') as String).videoCodec;

      final int type = data['cameraType'] ?? CameraType.front.type;

      await _rtcManager.setSubscriberRemoteSdp(
        targetId: data['targetId'],
        sdp: data['offer'],
        audioEnabled: data['audioEnabled'] ?? false,
        videoEnabled: data['videoEnabled'] ?? false,
        isScreenSharing: data['isScreenSharing'] ?? false,
        isE2eeEnabled: data['isE2eeEnabled'] ?? false,
        isHandRaising: data['isHandRaising'] ?? false,
        type: CameraType.values[type],
        codec: codec,
      );
    });

    _socket?.on(SocketEvent.participantHasLeftSSC, (data) {
      /// targetId
      if (data == null) return;

      final participantId = data['targetId'];

      _rtcManager.participantHasLeft(participantId);
    });

    _socket?.on(SocketEvent.publisherCandidateSSC, (data) {
      /// candidate json
      if (data == null) return;

      final RTCIceCandidate candidate = RTCIceCandidate(
        data['candidate'],
        data['sdpMid'],
        data['sdpMLineIndex'],
      );

      _rtcManager.addPublisherCandidate(candidate);
    });

    _socket?.on(SocketEvent.subscriberCandidateSSC, (data) {
      /// targetId, candidate json

      if (data == null) return;

      final Map<String, dynamic> candidateMap = data['candidate'];

      final String participantId = data['targetId'];
      final RTCIceCandidate candidate = RTCIceCandidate(
        candidateMap['candidate'],
        candidateMap['sdpMid'],
        candidateMap['sdpMLineIndex'],
      );

      _rtcManager.addSubscriberCandidate(participantId, candidate);
    });

    _socket?.on(SocketEvent.setE2eeEnabledSSC, (data) {
      /// targetId, isEnabled
      if (data == null) return;

      final String participantId = data['participantId'];
      final bool isEnabled = data['isEnabled'];

      _rtcManager.setE2eeEnabled(
        targetId: participantId,
        isEnabled: isEnabled,
      );
    });

    _socket?.on(SocketEvent.setAudioEnabledSSC, (data) {
      /// targetId, isEnabled
      if (data == null) return;

      final String participantId = data['participantId'];
      final bool isEnabled = data['isEnabled'];

      _rtcManager.setAudioEnabled(
        targetId: participantId,
        isEnabled: isEnabled,
      );
    });

    _socket?.on(SocketEvent.setVideoEnabledSSC, (data) {
      /// targetId, isEnabled
      if (data == null) return;

      final String participantId = data['participantId'];
      final bool isEnabled = data['isEnabled'];

      _rtcManager.setVideoEnabled(
        targetId: participantId,
        isEnabled: isEnabled,
      );
    });

    _socket?.on(SocketEvent.setCameraTypeSSC, (data) {
      /// targetId, isEnabled
      if (data == null) return;

      final String participantId = data['participantId'];
      final int type = data['type'];

      _rtcManager.setCameraType(
        targetId: participantId,
        type: CameraType.values[type],
      );
    });

    _socket?.on(SocketEvent.setScreenSharingSSC, (data) {
      /// targetId, isSharing
      if (data == null) return;

      final String participantId = data['participantId'];
      final bool isSharing = data['isSharing'];

      _rtcManager.setScreenSharing(
        targetId: participantId,
        isSharing: isSharing,
      );
    });

    _socket!.on(SocketEvent.publisherRenegotiationSSC, (data) {
      if (data == null) return;

      final String sdp = data['sdp'];

      _rtcManager.setPublisherRemoteSdp(sdp);
    });

    _socket!.on(SocketEvent.subscriberRenegotiationSSC, (data) {
      if (data == null) return;

      final String targetId = data['targetId'];
      final String sdp = data['sdp'];

      _rtcManager.handleSubscriberRenegotiation(
        targetId: targetId,
        sdp: sdp,
      );
    });

    _socket?.on(SocketEvent.subtitleSSC, (data) {
      if (data == null) return;

      final participantId = data['participantId'];
      final content = data['transcription'];

      WaterbusSdk.onSubtitle?.call(
        Subtitle(participant: participantId, content: content),
      );
    });

    _socket?.on(SocketEvent.handRaisingSSC, (data) {
      if (data == null) return;

      final String participantId = data['participantId'];
      final bool isRaising = data['isRaising'];
      _rtcManager.setHandRaising(
        targetId: participantId,
        isRaising: isRaising,
      );
    });

    _socket?.on(SocketEvent.startRecordSSC, (data) {
      _rtcManager.setIsRecording(isRecording: true);
    });

    _socket?.on(SocketEvent.stopRecordSSC, (data) {
      _rtcManager.setIsRecording(isRecording: false);
    });

    _socket?.on(SocketEvent.sendPodNameSSC, (data) {
      if (data == null) return;

      _podName = data['podName'];
    });

    _socket?.on(SocketEvent.destroy, (data) {
      if (data == null) return;

      final String podName = data['podName'];

      if (_podName == podName && _rtcManager.roomId != null) {
        reconnect(
          callbackConnected: () {
            _rtcManager.reconnect();
          },
        );
      }
    });

    _socket?.on(SocketEvent.sendMessageSSC, (data) async {
      if (data == null) return;

      final MessageModel message = MessageModel.fromMapSocket(data);

      final String dataDecrypted =
          await EncryptAES().decryptAES256(cipherText: message.data);

      WaterbusSdk.onMesssageChanged?.call(
        MessageSocketEvent(
          event: MessageEventEnum.create,
          message: message.copyWith(data: dataDecrypted),
        ),
      );
    });

    _socket?.on(SocketEvent.updateMessageSSC, (data) async {
      if (data == null) return;

      final MessageModel message = MessageModel.fromMapSocket(data);

      final String dataDecrypted =
          await EncryptAES().decryptAES256(cipherText: message.data);

      WaterbusSdk.onMesssageChanged?.call(
        MessageSocketEvent(
          event: MessageEventEnum.update,
          message: message.copyWith(data: dataDecrypted),
        ),
      );
    });

    _socket?.on(SocketEvent.deleteMessageSSC, (data) {
      if (data == null) return;

      final MessageModel message = MessageModel.fromMapSocket(data);

      WaterbusSdk.onMesssageChanged?.call(
        MessageSocketEvent(event: MessageEventEnum.delete, message: message),
      );
    });

    _socket?.on(SocketEvent.newInvitationSSC, (data) {
      if (data == null) return;
      final Meeting meeting = Meeting.fromMapSocket(data['meeting']);

      WaterbusSdk.onConversationChanged?.call(
        ConversationSocketEvent(
          event: ConversationEventEnum.newInvitaion,
          conversation: meeting,
        ),
      );
    });

    _socket?.on(SocketEvent.newMemberJoinedSSC, (data) {
      if (data == null) return;
      final Member member = Member.fromMapSocket(data);

      WaterbusSdk.onConversationChanged?.call(
        ConversationSocketEvent(
          event: ConversationEventEnum.newMemberJoined,
          member: member,
        ),
      );
    });

    // White board
    _socket?.on(SocketEvent.startWhiteBoardSSC, (data) {
      if (data == null) return;

      final List rawData = data;

      final List<DrawModel> paints =
          rawData.map((data) => DrawModel.fromMap(data)).toList();

      _whiteBoardManager.onRemoteBoardChanged(
        paints,
        DrawActionEnum.updateAdd,
      );
    });

    _socket?.on(SocketEvent.updateWhiteBoardSSC, (data) {
      if (data == null) return;

      final String actionMap = data['action'];
      final DrawActionEnum action = actionMap.drawAction;
      final List rawData = data['paints'];
      final List<DrawModel> paints =
          rawData.map((data) => DrawModel.fromMap(data)).toList();

      _whiteBoardManager.onRemoteBoardChanged(paints, action);
    });

    _socket?.on(SocketEvent.cleanWhiteBoardSSC, (data) {
      _whiteBoardManager.cleanWhiteBoard(shouldEmit: false);
    });
  });
}