import 'dart:async'; import 'dart:convert'; import 'package:audioplayers/audioplayers.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:star_lock/app_settings/app_settings.dart'; import 'package:star_lock/talk/other/audio_player_manager.dart'; import 'package:star_lock/talk/startChart/constant/payload_type_constant.dart'; import 'package:star_lock/talk/startChart/constant/udp_constant.dart'; import 'package:star_lock/talk/startChart/entity/scp_message.dart'; import 'package:star_lock/talk/startChart/handle/other/overtime_timer_manger.dart'; import 'package:star_lock/talk/startChart/handle/other/talk_data_repository.dart'; import 'package:star_lock/talk/startChart/proto/generic.pb.dart'; import 'package:star_lock/talk/startChart/proto/talk_data.pb.dart'; import 'package:star_lock/talk/startChart/start_chart_manage.dart'; import 'package:star_lock/talk/startChart/start_chart_talk_status.dart'; class ScpMessageBaseHandle { final startChartManage = StartChartManage(); /// 分包缓冲区 // 存储每个 messageId 对应的分包数据 static Map>> _packetBuffer = {}; final Map _packetTimers = {}; final Duration _timeoutDuration = Duration(seconds: 10); // 分包组包最大超时时间 // 通话数据流的单例流数据处理类 final TalkDataRepository talkDataRepository = TalkDataRepository.instance; final audioManager = AudioPlayerManager(); // 通话保持超时监听定时器管理 final talkePingOverTimeTimerManager = OverTimeTimerManager( timeoutInSeconds: 5, ); // 通话数据超时定时器 final talkDataOverTimeTimerManager = OverTimeTimerManager( timeoutInSeconds: 3, ); // 回复成功消息 void replySuccessMessage(ScpMessage scpMessage) { startChartManage.sendGenericRespSuccessMessage( ToPeerId: scpMessage.FromPeerId!, FromPeerId: scpMessage.ToPeerId!, PayloadType: scpMessage.PayloadType!, ); } // 获取 StartChartTalkStatus 的唯一实例 StartChartTalkStatus talkStatus = StartChartTalkStatus.instance; bool checkGenericRespSuccess(GenericResp genericResp) { if (genericResp == null) return false; final code = genericResp.code; final message = genericResp.message; return code == UdpConstant.genericRespSuccessCode && message == UdpConstant.genericRespSuccessMsg; } void log({required String text}) { AppLog.log('==========${text}'); } // 播放铃声 void playRingtone() async { await audioManager.playRingtone(); } // 停止播放铃声 void stopRingtone() async { await audioManager.stopRingtone(); } /// 处理分包逻辑 /// 如果没有收到所有包则返回null dynamic handleFragmentedPayload({ required int messageId, required int spTotal, required int spIndex, required List byte, required int payloadType, }) { // 初始化分包列表 String key = '$messageId-$payloadType'; if (!_packetBuffer.containsKey(messageId)) { _packetBuffer[key] = List.filled(spTotal, []); _startTimer(key); } // 检查分包索引是否在合法范围内 if (spIndex < 1 || spIndex > spTotal) { print( 'Invalid spTotal: $spTotal spIndex: $spIndex for messageId: $messageId'); return null; } // 存储当前分包 _packetBuffer[key]![spIndex - 1] = byte; // 检查是否接收到所有分包 if (_packetBuffer[key]!.every((packet) => packet.isNotEmpty)) { // 重组所有分包 List completePayload = _packetBuffer[key]!.expand((packet) => packet).toList(); // 清除已重组和超时的分包数据 _clearPacketData(key); // 解析完整的 payload if (payloadType == PayloadTypeConstant.talkData) { final TalkData talkData = TalkData(); talkData.mergeFromBuffer(completePayload); return talkData; } else if (payloadType == PayloadTypeConstant.echoTest) { return completePayload; } else { String payload = utf8.decode(completePayload); return payload; } } else { // 如果分包尚未接收完全,返回 null 或其他指示符 return null; } } // 启动定时器 void _startTimer(String key) { _packetTimers[key]?.cancel(); _packetTimers[key] = Timer(_timeoutDuration, () { _clearPacketData(key); }); } // 清除分包数据和定时器 void _clearPacketData(String key) { _packetBuffer.remove(key); _packetTimers.remove(key)?.cancel(); } }