fix:增加分包发送、接收分包数据后的组包逻辑
This commit is contained in:
parent
d6322c21ad
commit
ba47b2731b
@ -22,8 +22,8 @@ import 'package:star_lock/talk/startChart/proto/talk_request.pb.dart';
|
|||||||
|
|
||||||
class ScpMessage {
|
class ScpMessage {
|
||||||
/// 分包缓冲区
|
/// 分包缓冲区
|
||||||
/// key:MessageId
|
// 存储每个 messageId 对应的分包数据
|
||||||
static Map<int, List<int>> _buffer = {};
|
static Map<int, List<List<int>>> _packetBuffer = {};
|
||||||
|
|
||||||
ScpMessage({
|
ScpMessage({
|
||||||
this.ProtocolFlag,
|
this.ProtocolFlag,
|
||||||
@ -154,7 +154,7 @@ class ScpMessage {
|
|||||||
// Payload (字符串,转换为字节)
|
// Payload (字符串,转换为字节)
|
||||||
if (Payload != null && Payload is String) {
|
if (Payload != null && Payload is String) {
|
||||||
bytes.addAll(utf8.encode(Payload!));
|
bytes.addAll(utf8.encode(Payload!));
|
||||||
} else {
|
} else if (Payload != null) {
|
||||||
// 如果不是字符串则需要外部转为字节数组,这里直接添加
|
// 如果不是字符串则需要外部转为字节数组,这里直接添加
|
||||||
bytes.addAll(Payload);
|
bytes.addAll(Payload);
|
||||||
}
|
}
|
||||||
@ -302,8 +302,22 @@ class ScpMessage {
|
|||||||
return heartbeatResponse;
|
return heartbeatResponse;
|
||||||
case PayloadTypeConstant.echoTest:
|
case PayloadTypeConstant.echoTest:
|
||||||
// 回声测试
|
// 回声测试
|
||||||
String payload = utf8.decode(byte);
|
if (spTotal != null &&
|
||||||
return payload;
|
spTotal > 1 &&
|
||||||
|
messageId != null &&
|
||||||
|
spIndex != null) {
|
||||||
|
// 分包处理
|
||||||
|
return _handleFragmentedPayload(
|
||||||
|
messageId: messageId,
|
||||||
|
spTotal: spTotal,
|
||||||
|
spIndex: spIndex,
|
||||||
|
byte: byte,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// 如果 spTotal 为 1 或者没有分包信息,直接处理 byte 数据
|
||||||
|
String payload = utf8.decode(byte);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
case PayloadTypeConstant.gatewayReset:
|
case PayloadTypeConstant.gatewayReset:
|
||||||
// 初始化网关
|
// 初始化网关
|
||||||
if (messageType == MessageTypeConstant.Resp) {
|
if (messageType == MessageTypeConstant.Resp) {
|
||||||
@ -428,22 +442,9 @@ class ScpMessage {
|
|||||||
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
final GenericResp genericResp = GenericResp.fromBuffer(byte);
|
||||||
return genericResp;
|
return genericResp;
|
||||||
} else if (messageType == MessageTypeConstant.RealTimeData) {
|
} else if (messageType == MessageTypeConstant.RealTimeData) {
|
||||||
if (spTotal != null && spTotal > 1) {
|
// 没有分包直接解析
|
||||||
// 处理分包
|
final TalkData talkData = TalkData.fromBuffer(byte);
|
||||||
final List<int> subPackageBytes = _subPackage(
|
return talkData;
|
||||||
spTotal: spTotal!,
|
|
||||||
spIndex: spIndex!,
|
|
||||||
bytes: byte,
|
|
||||||
messageId: messageId!,
|
|
||||||
);
|
|
||||||
// 没有分包直接解析
|
|
||||||
final TalkData talkData = TalkData.fromBuffer(subPackageBytes);
|
|
||||||
return talkData;
|
|
||||||
} else {
|
|
||||||
// 没有分包直接解析
|
|
||||||
final TalkData talkData = TalkData.fromBuffer(byte);
|
|
||||||
return talkData;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
String payload = utf8.decode(byte);
|
String payload = utf8.decode(byte);
|
||||||
return payload;
|
return payload;
|
||||||
@ -465,19 +466,11 @@ class ScpMessage {
|
|||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// _log(text: '❌反序列化udp数据时遇到错误----》$e');
|
_log(text: '❌反序列化udp数据时遇到错误----》$e');
|
||||||
|
// 尝试打印原始字节数组以供调试
|
||||||
// // 尝试打印原始字节数组以供调试
|
|
||||||
_log(
|
_log(
|
||||||
text:
|
text:
|
||||||
'原始字节数组: ${byte.sublist(0, 20).map((b) => b.toRadixString(16)).join(" ")}');
|
'原始字节数组: ${byte.sublist(0, 20).map((b) => b.toRadixString(16)).join(" ")}');
|
||||||
//
|
|
||||||
// // 如果是Protobuf相关的异常,尝试提供更多信息
|
|
||||||
// if (e is InvalidProtocolBufferException || e is FormatException) {
|
|
||||||
// _log(
|
|
||||||
// text:
|
|
||||||
// '反序列化失败的payloadType: $payloadType, messageType: $messageType');
|
|
||||||
// }
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -500,22 +493,37 @@ class ScpMessage {
|
|||||||
AppLog.log('=====${text}');
|
AppLog.log('=====${text}');
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 处理分包情况
|
/// 处理分包逻辑
|
||||||
static List<int> _subPackage({
|
/// 如果没有收到所有包则返回null
|
||||||
|
static String? _handleFragmentedPayload({
|
||||||
required int messageId,
|
required int messageId,
|
||||||
required int spTotal,
|
required int spTotal,
|
||||||
required int spIndex,
|
required int spIndex,
|
||||||
required List<int> bytes,
|
required List<int> byte,
|
||||||
}) {
|
}) {
|
||||||
if (_buffer.containsKey(messageId)) {
|
// 初始化分包列表
|
||||||
// 存在这个key就追加
|
if (!_packetBuffer.containsKey(messageId)) {
|
||||||
final List<int> bytesList = _buffer[messageId]!;
|
_packetBuffer[messageId] = List.filled(spTotal, []);
|
||||||
bytesList.addAll(bytes);
|
}
|
||||||
_buffer[messageId] = bytesList;
|
|
||||||
} else {
|
// 存储当前分包
|
||||||
// 如果不存在这个key,就新增进去
|
_packetBuffer[messageId]![spIndex - 1] = byte;
|
||||||
_buffer.putIfAbsent(messageId, () => bytes);
|
|
||||||
|
// 检查是否接收到所有分包
|
||||||
|
if (_packetBuffer[messageId]!.every((packet) => packet.isNotEmpty)) {
|
||||||
|
// 重组所有分包
|
||||||
|
List<int> completePayload =
|
||||||
|
_packetBuffer[messageId]!.expand((packet) => packet).toList();
|
||||||
|
|
||||||
|
// 清除已重组的分包数据
|
||||||
|
_packetBuffer.remove(messageId);
|
||||||
|
|
||||||
|
// 解析完整的 payload
|
||||||
|
String payload = utf8.decode(completePayload);
|
||||||
|
return payload;
|
||||||
|
} else {
|
||||||
|
// 如果分包尚未接收完全,返回 null 或其他指示符
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,7 +75,7 @@ class StartChartManage {
|
|||||||
int talkDataIntervalTime = 10; // 通话数据的消息间隔(ms)
|
int talkDataIntervalTime = 10; // 通话数据的消息间隔(ms)
|
||||||
Timer? talkDataTimer; // 发送通话数据消息定时器
|
Timer? talkDataTimer; // 发送通话数据消息定时器
|
||||||
|
|
||||||
final int _maxPayloadSize = 50 * 1024; // 分包大小
|
final int _maxPayloadSize = 8 * 1024; // 分包大小
|
||||||
|
|
||||||
// 默认通话的期望数据格式
|
// 默认通话的期望数据格式
|
||||||
TalkExpect defaultTalkExpect = TalkExpect(
|
TalkExpect defaultTalkExpect = TalkExpect(
|
||||||
@ -111,7 +111,7 @@ class StartChartManage {
|
|||||||
Future<void> _clientRegister() async {
|
Future<void> _clientRegister() async {
|
||||||
final StarChartRegisterNodeEntity? registerNodeEntity =
|
final StarChartRegisterNodeEntity? registerNodeEntity =
|
||||||
await Storage.getStarChartRegisterNodeInfo();
|
await Storage.getStarChartRegisterNodeInfo();
|
||||||
if (registerNodeEntity != null) {
|
if (registerNodeEntity != null && registerNodeEntity.peer?.id != null) {
|
||||||
_log(text: '获取到星图注册节点信息:$registerNodeEntity');
|
_log(text: '获取到星图注册节点信息:$registerNodeEntity');
|
||||||
FromPeerId = registerNodeEntity.peer!.id ?? '';
|
FromPeerId = registerNodeEntity.peer!.id ?? '';
|
||||||
} else {
|
} else {
|
||||||
@ -215,7 +215,7 @@ class StartChartManage {
|
|||||||
|
|
||||||
// 发送上线消息
|
// 发送上线消息
|
||||||
Future<void> _sendOnlineMessage() async {
|
Future<void> _sendOnlineMessage() async {
|
||||||
_log(text: '发送上线消息');
|
_log(text: '发送上线消息,是否已经上线:$isOnlineStartChartServer');
|
||||||
if (isOnlineStartChartServer) {
|
if (isOnlineStartChartServer) {
|
||||||
_log(text: '星图已上线,请勿重复发送上线消息');
|
_log(text: '星图已上线,请勿重复发送上线消息');
|
||||||
return;
|
return;
|
||||||
@ -281,17 +281,21 @@ class StartChartManage {
|
|||||||
|
|
||||||
// 发送回声测试消息
|
// 发送回声测试消息
|
||||||
void sendEchoMessage({required List<int> payload}) async {
|
void sendEchoMessage({required List<int> payload}) async {
|
||||||
String toPeerId = '2vzXdjdzipJBpWpJxhiRzCFXrDKk54t3YJ7EjYPSRuij';
|
String toPeerId = 'G7fzJkbS5MigMqnbTCQVk7VspcDsnGeikJpQwS8fbhim';
|
||||||
|
|
||||||
|
// 计算需要分多少个包发送
|
||||||
final int totalPackets = (payload.length / _maxPayloadSize).ceil();
|
final int totalPackets = (payload.length / _maxPayloadSize).ceil();
|
||||||
|
// 循环遍历
|
||||||
for (int i = 0; i < totalPackets; i++) {
|
for (int i = 0; i < totalPackets; i++) {
|
||||||
int start = i * _maxPayloadSize;
|
int start = i * _maxPayloadSize;
|
||||||
int end = (i + 1) * _maxPayloadSize;
|
int end = (i + 1) * _maxPayloadSize;
|
||||||
if (end > payload.length) {
|
if (end > payload.length) {
|
||||||
end = payload.length;
|
end = payload.length;
|
||||||
}
|
}
|
||||||
|
// 取到分包数据
|
||||||
List<int> packet = payload.sublist(start, end);
|
List<int> packet = payload.sublist(start, end);
|
||||||
|
|
||||||
|
// 组装分包数据
|
||||||
final message = MessageCommand.echoMessage(
|
final message = MessageCommand.echoMessage(
|
||||||
ToPeerId: toPeerId,
|
ToPeerId: toPeerId,
|
||||||
FromPeerId: FromPeerId,
|
FromPeerId: FromPeerId,
|
||||||
@ -300,22 +304,14 @@ class StartChartManage {
|
|||||||
SpIndex: i + 1,
|
SpIndex: i + 1,
|
||||||
MessageId: MessageCommand.getNextMessageId(toPeerId, increment: false),
|
MessageId: MessageCommand.getNextMessageId(toPeerId, increment: false),
|
||||||
);
|
);
|
||||||
|
// 发送消息
|
||||||
await _sendMessage(message: message);
|
await _sendMessage(message: message);
|
||||||
_log(
|
_log(
|
||||||
text:
|
text:
|
||||||
'发送回声测试消息=====SpTotal:$totalPackets,SpIndex:${i + 1},packet:${packet.length}');
|
'发送回声测试分包消息=====SpTotal:$totalPackets,SpIndex:${i + 1},packet:${packet.length}');
|
||||||
}
|
}
|
||||||
// 分包发送完了递增一下id
|
// 分包发送完了递增一下id
|
||||||
MessageCommand.getNextMessageId(toPeerId);
|
MessageCommand.getNextMessageId(toPeerId);
|
||||||
// final message = MessageCommand.echoMessage(
|
|
||||||
// ToPeerId: echoPeerId,
|
|
||||||
// FromPeerId: FromPeerId,
|
|
||||||
// payload: [],
|
|
||||||
// SpIndex: 0,
|
|
||||||
// SpTotal: 0,
|
|
||||||
// );
|
|
||||||
// await _sendMessage(message: message);
|
|
||||||
// _log(text: '发送回声测试消息');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送网关初始化消息
|
// 发送网关初始化消息
|
||||||
@ -372,7 +368,7 @@ class StartChartManage {
|
|||||||
ToPeerId: ToPeerId,
|
ToPeerId: ToPeerId,
|
||||||
FromPeerId: FromPeerId,
|
FromPeerId: FromPeerId,
|
||||||
PayloadType: PayloadType,
|
PayloadType: PayloadType,
|
||||||
MessageId: MessageCommand.getNextMessageId(ToPeerId, increment: true),
|
MessageId: MessageCommand.getNextMessageId(ToPeerId, increment: false),
|
||||||
);
|
);
|
||||||
await _sendMessage(message: message);
|
await _sendMessage(message: message);
|
||||||
}
|
}
|
||||||
@ -386,7 +382,7 @@ class StartChartManage {
|
|||||||
ToPeerId: ToPeerId,
|
ToPeerId: ToPeerId,
|
||||||
FromPeerId: FromPeerId,
|
FromPeerId: FromPeerId,
|
||||||
PayloadType: PayloadType,
|
PayloadType: PayloadType,
|
||||||
MessageId: MessageCommand.getNextMessageId(ToPeerId, increment: true),
|
MessageId: MessageCommand.getNextMessageId(ToPeerId, increment: false),
|
||||||
);
|
);
|
||||||
await _sendMessage(message: message);
|
await _sendMessage(message: message);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user