hi-client/lib/app/utils/kr_latency_tester.dart
speakeloudest a78b40c339
Some checks failed
Build Windows / build (push) Has been cancelled
Build Windows / 编译 libcore (Windows) (20.15.1) (push) Has been cancelled
feat: 修改代码冲突
2025-11-09 22:43:57 -08:00

152 lines
4.3 KiB
Dart

import 'dart:io';
import 'dart:async';
import 'kr_log_util.dart';
/// 真正的节点延迟测试工具
class KRLatencyTester {
/// TCP 连接测试延迟(真实测试)
/// 返回延迟毫秒数,失败返回 65535
static Future<int> testTcpLatency({
required String host,
required int port,
Duration timeout = const Duration(seconds: 5),
}) async {
Socket? socket;
final stopwatch = Stopwatch();
try {
KRLogUtil.kr_i('🔌 开始测试: $host:$port', tag: 'LatencyTester');
stopwatch.start();
// 尝试 TCP 连接
socket = await Socket.connect(
host,
port,
timeout: timeout,
);
stopwatch.stop();
final latency = stopwatch.elapsedMilliseconds;
KRLogUtil.kr_i('✅ 测试成功: $host:$port - ${latency}ms', tag: 'LatencyTester');
return latency;
} on SocketException catch (e) {
stopwatch.stop();
KRLogUtil.kr_w('❌ 连接失败: $host:$port - ${e.message}', tag: 'LatencyTester');
return 65535;
} on TimeoutException catch (e) {
stopwatch.stop();
KRLogUtil.kr_w('⏱️ 连接超时: $host:$port - $e', tag: 'LatencyTester');
return 65535;
} catch (e) {
stopwatch.stop();
KRLogUtil.kr_e('❌ 测试异常: $host:$port - $e', tag: 'LatencyTester');
return 65535;
} finally {
// 确保关闭连接
try {
await socket?.close();
} catch (e) {
// 忽略关闭错误
}
}
}
/// 批量测试多个节点延迟(并发测试)
/// 返回 Map<节点tag, 延迟ms>
static Future<Map<String, int>> testMultipleNodes({
required List<MapEntry<String, SocketAddress>> nodes,
int concurrency = 10, // 并发数
Duration timeout = const Duration(seconds: 5),
}) async {
final results = <String, int>{};
final List<List<MapEntry<String, SocketAddress>>> batches = [];
// 分批处理
for (int i = 0; i < nodes.length; i += concurrency) {
batches.add(
nodes.sublist(i, i + concurrency > nodes.length ? nodes.length : i + concurrency)
);
}
KRLogUtil.kr_i('📊 开始批量测试: ${nodes.length} 个节点,分 ${batches.length} 批,每批 $concurrency', tag: 'LatencyTester');
int completedCount = 0;
// 逐批测试
for (int batchIndex = 0; batchIndex < batches.length; batchIndex++) {
final batch = batches[batchIndex];
KRLogUtil.kr_i('📦 测试第 ${batchIndex + 1}/${batches.length} 批(${batch.length} 个节点)', tag: 'LatencyTester');
// 并发测试当前批次
final futures = batch.map((node) async {
final tag = node.key;
final address = node.value;
final latency = await testTcpLatency(
host: address.host,
port: address.port,
timeout: timeout,
);
completedCount++;
if (completedCount % 5 == 0 || completedCount == nodes.length) {
KRLogUtil.kr_i('📈 测试进度: $completedCount/${nodes.length}', tag: 'LatencyTester');
}
return MapEntry(tag, latency);
}).toList();
// 等待当前批次完成
final batchResults = await Future.wait(futures);
// 收集结果
for (final result in batchResults) {
results[result.key] = result.value;
}
}
// 统计结果
final successCount = results.values.where((latency) => latency < 65535).length;
final failCount = results.length - successCount;
KRLogUtil.kr_i('✅ 批量测试完成', tag: 'LatencyTester');
KRLogUtil.kr_i('📊 成功: $successCount, 失败: $failCount', tag: 'LatencyTester');
// 显示延迟最低的前3个
final successNodes = results.entries
.where((e) => e.value < 65535)
.toList()
..sort((a, b) => a.value.compareTo(b.value));
if (successNodes.isNotEmpty) {
KRLogUtil.kr_i('🏆 延迟最低的前3个节点:', tag: 'LatencyTester');
for (int i = 0; i < 3 && i < successNodes.length; i++) {
KRLogUtil.kr_i(' ${i + 1}. ${successNodes[i].key}: ${successNodes[i].value}ms', tag: 'LatencyTester');
}
}
return results;
}
}
/// 节点地址信息
class SocketAddress {
final String host;
final int port;
SocketAddress(this.host, this.port);
@override
String toString() => '$host:$port';
}