From 5e781a5f00c0110b167ff453095d178ef5711b61 Mon Sep 17 00:00:00 2001 From: liyi Date: Thu, 13 Mar 2025 13:39:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E8=B0=83=E6=95=B4=E7=BB=84=E5=8C=85?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handle/scp_message_base_handle.dart | 104 ++++++++++++++---- 1 file changed, 84 insertions(+), 20 deletions(-) diff --git a/lib/talk/starChart/handle/scp_message_base_handle.dart b/lib/talk/starChart/handle/scp_message_base_handle.dart index c1225f0e..f4b68024 100644 --- a/lib/talk/starChart/handle/scp_message_base_handle.dart +++ b/lib/talk/starChart/handle/scp_message_base_handle.dart @@ -43,7 +43,7 @@ class ScpMessageBaseHandle { // 存储每个 messageId 对应的分包数据 static Map>> _packetBuffer = {}; final Map _packetTimers = {}; - final Duration _timeoutDuration = Duration(seconds: 10); // 分包组包最大超时时间 + final Duration _timeoutDuration = Duration(seconds: 3); // 分包组包最大超时时间 // 通话数据流的单例流数据处理类 final TalkDataRepository talkDataRepository = TalkDataRepository.instance; @@ -106,40 +106,104 @@ class ScpMessageBaseHandle { required int payloadType, }) { // 初始化分包列表 - String key = '$messageId-$payloadType'; - if (!_packetBuffer.containsKey(key)) { - _packetBuffer[key] = List.filled(spTotal, []); - _startTimer(key); - } + // 使用更高效的key生成方式 + final key = '${messageId}_$payloadType'; + + // 打印每个包的信息 + // AppLog.log( + // '📦 收到分包 - MessageId: $messageId, 总包数: $spTotal, 当前包序号: $spIndex'); // 检查分包索引是否在合法范围内 if (spIndex < 1 || spIndex > spTotal) { - // print( - // 'Invalid spTotal: $spTotal spIndex: $spIndex for messageId: $messageId'); + AppLog.log( + '❌ 分包序号异常 - MessageId: $messageId, 总包数: $spTotal, 无效包序号: $spIndex'); return null; } + // 检查分包索引是否在合法范围内(提前检查可以避免后续无效操作) + if (spIndex < 1 || spIndex > spTotal) return null; + + // 初始化分包列表(使用固定长度列表提高性能) + var packets = _packetBuffer[key]; + if (packets == null) { + // 预分配固定大小的列表,避免动态扩容 + packets = List>.filled(spTotal, const [], growable: false); + _packetBuffer[key] = packets; + _startTimer(key); + // AppLog.log('📝 新建分包缓存 - MessageId: $messageId, 预期总包数: $spTotal'); + } + // 存储当前分包 - _packetBuffer[key]![spIndex - 1] = byte; + packets[spIndex - 1] = byte; - // 检查是否接收到所有分包 - if (_packetBuffer[key]!.every((packet) => packet.isNotEmpty)) { - // 重组所有分包 - Uint8List completePayload = Uint8List.fromList( - _packetBuffer[key]!.expand((packet) => packet).toList()); - // 清除已重组和超时的分包数据 + // 优化检查逻辑,使用循环替代every + var isComplete = true; + var totalLength = 0; + for (var i = 0; i < packets.length; i++) { + if (packets[i].isEmpty) { + isComplete = false; + } else { + totalLength += packets[i].length; + } + } + + if (isComplete) { + // 预分配确切大小的buffer,避免扩容 + final buffer = Uint8List(totalLength); + var offset = 0; + + // 直接复制数据,避免使用expand + for (var packet in packets) { + buffer.setRange(offset, offset + packet.length, packet); + offset += packet.length; + } + + // 清理资源 _clearPacketData(key); - // 使用重组的包构造成TalkData + // 构造TalkData if (payloadType == PayloadTypeConstant.talkData) { final talkData = TalkData(); - talkData.mergeFromBuffer(completePayload); + talkData.mergeFromBuffer(buffer); return talkData; } - } else { - // 如果分包尚未接收完全,返回 null 或其他指示符 - return null; } + + return null; + + // if (!_packetBuffer.containsKey(key)) { + // _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)) { + // // 重组所有分包 + // Uint8List completePayload = Uint8List.fromList( + // _packetBuffer[key]!.expand((packet) => packet).toList()); + // // 清除已重组和超时的分包数据 + // _clearPacketData(key); + // + // // 使用重组的包构造成TalkData + // if (payloadType == PayloadTypeConstant.talkData) { + // final talkData = TalkData(); + // talkData.mergeFromBuffer(completePayload); + // return talkData; + // } + // } else { + // // 如果分包尚未接收完全,返回 null 或其他指示符 + // return null; + // } } // 启动定时器