|
|
|
@ -84,6 +84,9 @@ class CallController extends GetxController { |
|
|
|
int _callDurationSeconds = 0; |
|
|
|
final RxInt callDurationSeconds = RxInt(0); |
|
|
|
|
|
|
|
// 通话超时计时器(发起方等待对方接听的30秒超时) |
|
|
|
Timer? _callTimeoutTimer; |
|
|
|
|
|
|
|
// 远端用户UID(用于显示远端视频) |
|
|
|
final Rxn<int> remoteUid = Rxn<int>(); |
|
|
|
|
|
|
|
@ -155,6 +158,8 @@ class CallController extends GetxController { |
|
|
|
'📞 [CallController] 收到 accept 消息,设置 remoteUid: ${remoteUid.value}', |
|
|
|
); |
|
|
|
} |
|
|
|
// 取消超时计时器(对方已接听) |
|
|
|
_stopCallTimeoutTimer(); |
|
|
|
// 发起方收到 accept 消息后,启动通话计时器 |
|
|
|
_startCallTimer(); |
|
|
|
print('📞 [CallController] 收到 accept 消息,已启动通话计时器'); |
|
|
|
@ -170,6 +175,8 @@ class CallController extends GetxController { |
|
|
|
} else if (event == 'reject') { |
|
|
|
// 发起方收到 reject 消息,执行退出逻辑 |
|
|
|
print('📞 [CallController] 收到 reject 消息,执行退出逻辑'); |
|
|
|
// 取消超时计时器(对方已拒绝) |
|
|
|
_stopCallTimeoutTimer(); |
|
|
|
final channelId = messageData['channelId'] as String?; |
|
|
|
if (channelId != null && channelId.isNotEmpty) { |
|
|
|
RTMManager.instance.unsubscribe(channelId); |
|
|
|
@ -323,6 +330,9 @@ class CallController extends GetxController { |
|
|
|
await RTMManager.instance.subscribe(channelData.channelId); |
|
|
|
print('✅ [CallController] 已订阅 RTM 频道: ${channelData.channelId}'); |
|
|
|
|
|
|
|
// 启动30秒超时计时器(如果30秒内对方未接听,自动取消通话) |
|
|
|
_startCallTimeoutTimer(); |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
@ -472,8 +482,9 @@ class CallController extends GetxController { |
|
|
|
// 停止播放来电铃声(通话结束) |
|
|
|
stopCallAudio(); |
|
|
|
|
|
|
|
// 停止计时 |
|
|
|
// 停止计时和超时计时器 |
|
|
|
_stopCallTimer(); |
|
|
|
_stopCallTimeoutTimer(); |
|
|
|
|
|
|
|
// 清理通话会话和远端用户UID |
|
|
|
currentCall.value = null; |
|
|
|
@ -508,6 +519,28 @@ class CallController extends GetxController { |
|
|
|
callDurationSeconds.value = 0; |
|
|
|
} |
|
|
|
|
|
|
|
/// 启动通话超时计时器(30秒后如果对方未接听,自动取消通话) |
|
|
|
void _startCallTimeoutTimer() { |
|
|
|
_callTimeoutTimer?.cancel(); |
|
|
|
_callTimeoutTimer = Timer(Duration(seconds: 30), () { |
|
|
|
final callSession = currentCall.value; |
|
|
|
// 如果是发起方且对方未接听(通话时长仍为0且remoteUid为null),自动取消通话 |
|
|
|
if (callSession != null && |
|
|
|
callSession.isInitiator && |
|
|
|
callDurationSeconds.value == 0 && |
|
|
|
remoteUid.value == null) { |
|
|
|
print('⏰ [CallController] 30秒超时,对方未接听,自动取消通话'); |
|
|
|
hangUpCall(); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
/// 停止通话超时计时器 |
|
|
|
void _stopCallTimeoutTimer() { |
|
|
|
_callTimeoutTimer?.cancel(); |
|
|
|
_callTimeoutTimer = null; |
|
|
|
} |
|
|
|
|
|
|
|
/// 发送通话消息 |
|
|
|
Future<bool> _sendCallMessage({ |
|
|
|
required String targetUserId, |
|
|
|
@ -685,6 +718,9 @@ class CallController extends GetxController { |
|
|
|
Future<void> hangUpCall() async { |
|
|
|
final callSession = currentCall.value; |
|
|
|
|
|
|
|
// 取消超时计时器 |
|
|
|
_stopCallTimeoutTimer(); |
|
|
|
|
|
|
|
// 如果是发起方且处于呼叫中状态(对方还没接听),先调用取消接口 |
|
|
|
if (callSession != null && |
|
|
|
callSession.isInitiator && |
|
|
|
@ -744,6 +780,9 @@ class CallController extends GetxController { |
|
|
|
SmartDialog.dismiss(); |
|
|
|
print('✅ [CallController] 已关闭视频通话邀请弹框'); |
|
|
|
|
|
|
|
// 取消超时计时器 |
|
|
|
_stopCallTimeoutTimer(); |
|
|
|
|
|
|
|
// 停止播放来电铃声 |
|
|
|
stopCallAudio(); |
|
|
|
|
|
|
|
@ -777,6 +816,7 @@ class CallController extends GetxController { |
|
|
|
void onClose() { |
|
|
|
stopCallAudio(); |
|
|
|
_stopCallTimer(); |
|
|
|
_stopCallTimeoutTimer(); |
|
|
|
currentCall.value = null; |
|
|
|
rtcChannel.value = null; |
|
|
|
remoteUid.value = null; |
|
|
|
|