parseMsg method

void parseMsg(
  1. ChatMessage message
)

Implementation

void parseMsg(ChatMessage message) async {
  Map ext = message.attributes ?? {};
  if (!ext.containsKey(kMsgType)) return;

  final from = message.from!;
  final msgType = ext[kMsgType];
  final callId = ext[kCallId] ?? "";
  final result = ext[kCallResult] ?? "";
  final callerDevId = ext[kCallerDevId] ?? "";
  final calleeDevId = ext[kCalleeDevId] ?? "";
  final channel = ext[kChannelName] ?? "";

  final isValid = ext[kCallStatus] ?? false;
  num type = ext[kCallType] ?? 0;

  final callType = ChatCallKitCallType.values[type.toInt()];
  Map<String, String>? callExt = (ext[kExt] ?? {}).cast<String, String>();

  // 收到邀请
  void parseInviteMsgExt() {
    // 已经在通话中或者呼叫中。直接返回
    if (model.curCall?.callId == callId || callTimerDic.containsKey(callId)) {
      return;
    }
    // 如果忙碌,直接返回 kBusyResult
    if (busy) {
      sendAnswerMsg(from, callId, kBusyResult, callerDevId);
      return;
    }

    // 将邀请放到收到的call中
    model.recvCalls[callId] = ChatCallKitCall(
      callId: callId,
      remoteUserAccount: from,
      remoteCallDevId: callerDevId,
      callType: callType,
      isCaller: false,
      channel: channel,
      ext: callExt,
    );

    // 发送应答
    sendAlertMsgToCaller(from, callId, callerDevId);
    // 启动应答计时器
    alertTimerDic[callId] =
        Timer.periodic(const Duration(seconds: 5), (timer) {
      // 时间到,取消应答计时
      timer.cancel();
      alertTimerDic.remove(callId);
    });
  }

  // 收到邀请应答
  void parseAlertMsgExt() {
    // 判断是我发送的邀请收到应答
    if (model.curDevId == callerDevId) {
      // 判断应答是否与本地存储数据呼应
      if (model.curCall?.callId == callId && callTimerDic.containsKey(from)) {
        // 告知对方,应答验证通过, 告知对方当前通话有效
        sendConfirmRingMsgToCallee(from, callId, true, calleeDevId);
      }
    } else {
      // 告知应答方,应答验证未通过,当前通话已经过期或者无效
      sendConfirmRingMsgToCallee(from, callId, false, calleeDevId);
    }
  }

  // 收到回复,可以确定通话有效,此处如果非忙可以弹窗。
  void parseConfirmRingMsgExt() {
    if (alertTimerDic.containsKey(callId) && calleeDevId == model.curDevId) {
      alertTimerDic.remove(callId)?.cancel();
      if (busy) {
        sendAnswerMsg(from, callId, kBusyResult, callerDevId);
        return;
      }
      if (model.recvCalls.containsKey(callId)) {
        // 验证通话有效,可以变为alerting状态, 如果无效则不需要处理
        if (isValid) {
          model.curCall = model.recvCalls[callId];
          model.recvCalls.clear();
          model.state = ChatCallKitCallState.alerting;
          alertTimerDic.forEach((key, value) {
            value.cancel();
          });
          alertTimerDic.clear();
        }
        model.recvCalls.remove(callId);
        ringTimer = Timer.periodic(timeoutDuration, (timer) {
          timer.cancel();
          ringTimer = null;
          if (model.curCall?.callId == callId) {
            handler.onCallEndReason.call(
              model.curCall!.callId,
              ChatCallKitCallEndReason.remoteNoResponse,
            );
            model.state = ChatCallKitCallState.idle;
          }
        });
      }
    }
  }

  // 收到呼叫取消
  void parseCancelCallMsgExt() {
    // 如当前已经应答,但还未加入会议,取消所以计时,并告知上层呼叫停止
    if (model.curCall?.callId == callId) {
      confirmTimer?.cancel();
      confirmTimer = null;
      handler.onCallEndReason
          .call(model.curCall!.callId, ChatCallKitCallEndReason.remoteCancel);
      model.state = ChatCallKitCallState.idle;
    } else {
      model.recvCalls.remove(callId);
    }
    alertTimerDic.remove(callId)?.cancel();
  }

  // 收到结果应答
  void parseAnswerMsgExt() {
    if (model.curCall?.callId == callId && model.curDevId == callerDevId) {
      // 如果为多人模式
      if (model.curCall?.callType == ChatCallKitCallType.multi) {
        // 对方拒绝
        if (result != kAcceptResult) {
          removeUser(from, ChatCallKitCallEndReason.busy);
        }

        Timer? timer = callTimerDic.remove(from);
        if (timer != null) {
          timer.cancel();
          sendConfirmAnswerMsgToCallee(from, callId, result, calleeDevId);
          if (result == kAcceptResult) {
            model.state = ChatCallKitCallState.answering;
            ringTimer?.cancel();
            ringTimer = null;
          }
        }
        onAnswer();
      } else {
        // 非多人模式,是呼出状态时
        if (model.state == ChatCallKitCallState.outgoing) {
          if (result == kAcceptResult) {
            model.state = ChatCallKitCallState.answering;
            ringTimer?.cancel();
            ringTimer = null;
          } else {
            handler.onCallEndReason.call(
              model.curCall!.callId,
              result == kRefuseResult
                  ? ChatCallKitCallEndReason.refuse
                  : ChatCallKitCallEndReason.busy,
            );
            model.state = ChatCallKitCallState.idle;
          }
        }
        onAnswer();
        // 用于被叫方多设备的情况,被叫方收到后可以进行仲裁,只有收到这条后被叫方才能进行通话
        sendConfirmAnswerMsgToCallee(from, callId, result, calleeDevId);
      }
    }
  }

  void parseConfirmCalleeMsgExt() {
    if (model.state == ChatCallKitCallState.alerting &&
        model.curCall?.callId == callId) {
      confirmTimer?.cancel();
      confirmTimer = null;
      if (model.curDevId == calleeDevId) {
        if (result == kAcceptResult) {
          model.state = ChatCallKitCallState.answering;
          ringTimer?.cancel();
          ringTimer = null;
          if (model.curCall?.callType != ChatCallKitCallType.audio_1v1) {
            // 更新本地摄像头数据
          }
          handler.onCallAccept.call();
          // 此处要开始获取声网token。
        } else {
          model.state = ChatCallKitCallState.idle;
          handler.onCallEndReason.call(model.curCall!.callId,
              ChatCallKitCallEndReason.handleOnOtherDevice);
        }
      }
    } else {
      if (model.recvCalls.remove(callId) != null) {
        alertTimerDic.remove(callId)?.cancel();
      }
    }
  }

  void parseVideoToVoiceMsg() {}

  if (msgType == kMsgTypeValue) {
    String action = ext[kAction];
    log("action:-----------$action, ${ext.toString()}");
    if (action == kInviteAction) {
      parseInviteMsgExt();
    } else if (action == kAlertAction) {
      parseAlertMsgExt();
    } else if (action == kCancelCallAction) {
      parseCancelCallMsgExt();
    } else if (action == kAnswerCallAction) {
      parseAnswerMsgExt();
    } else if (action == kConfirmRingAction) {
      parseConfirmRingMsgExt();
    } else if (action == kConfirmCalleeAction) {
      parseConfirmCalleeMsgExt();
    } else if (action == kVideoToVoice) {
      parseVideoToVoiceMsg();
    }
  }
}