parseMsg method
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();
}
}
}