From 78c20f9ae95531f9ea1044d565555618f39324c9 Mon Sep 17 00:00:00 2001 From: shanshanzhong Date: Sun, 9 Nov 2025 05:38:02 -0800 Subject: [PATCH] =?UTF-8?q?feat(utils):=20=E6=B7=BB=E5=8A=A0=E5=BB=B6?= =?UTF-8?q?=E8=BF=9F=E6=B5=8B=E8=AF=95=E5=B7=A5=E5=85=B7=E7=B1=BB=E7=94=A8?= =?UTF-8?q?=E4=BA=8ETCP=E8=BF=9E=E6=8E=A5=E5=BB=B6=E8=BF=9F=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增KRLatencyTester工具类,提供单节点和批量节点的TCP延迟测试功能 支持自定义超时时间和并发数,测试结果包含成功/失败状态和延迟时间 ``` ```msg refactor(home): 使用_storage直接保存闪连状态 将_saveQuickConnectStatus方法替换为直接调用_storage.kr_saveBool 简化代码逻辑,保持存储方式的一致性 --- .../controllers/kr_home_controller.dart | 2 +- lib/app/utils/kr_latency_tester.dart | 127 ++++++++++++++++++ 2 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 lib/app/utils/kr_latency_tester.dart diff --git a/lib/app/modules/kr_home/controllers/kr_home_controller.dart b/lib/app/modules/kr_home/controllers/kr_home_controller.dart index 122860d..df7bcc1 100755 --- a/lib/app/modules/kr_home/controllers/kr_home_controller.dart +++ b/lib/app/modules/kr_home/controllers/kr_home_controller.dart @@ -133,7 +133,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver { if (value != null) { isQuickConnectEnabled.value = value; // 保存闪连状态到本地存储 - await _saveQuickConnectStatus(value); + await _storage.kr_saveBool(key: _quickConnectKey, value: value); KRLogUtil.kr_i('闪连状态已更新: $value', tag: 'QuickConnect'); } } diff --git a/lib/app/utils/kr_latency_tester.dart b/lib/app/utils/kr_latency_tester.dart new file mode 100644 index 0000000..10e2f8a --- /dev/null +++ b/lib/app/utils/kr_latency_tester.dart @@ -0,0 +1,127 @@ +import 'dart:io'; +import 'dart:async'; +import 'package:kaer_with_panels/app/utils/kr_log_util.dart'; + +/// 延迟测试工具类 +/// 提供真实的 TCP 连接延迟测试功能 +class KRLatencyTester { + /// 测试单个节点的延迟 + /// + /// 参数: + /// - host: 主机地址 + /// - port: 端口号 + /// - timeout: 超时时间(毫秒) + /// + /// 返回: + /// - 延迟时间(毫秒),如果失败返回 65535 + static Future testNode({ + required String host, + required int port, + int timeout = 5000, + }) async { + try { + final stopwatch = Stopwatch()..start(); + + final socket = await Socket.connect( + host, + port, + timeout: Duration(milliseconds: timeout), + ).timeout(Duration(milliseconds: timeout)); + + stopwatch.stop(); + + // 立即关闭连接 + await socket.close(); + socket.destroy(); + + final latency = stopwatch.elapsedMilliseconds; + KRLogUtil.kr_i('✅ 延迟测试成功: $host:$port = ${latency}ms', tag: 'KRLatencyTester'); + + return latency; + } catch (e) { + KRLogUtil.kr_w('❌ 延迟测试失败: $host:$port - $e', tag: 'KRLatencyTester'); + return 65535; // 测试失败返回最大值 + } + } + + /// 批量测试多个节点的延迟 + /// + /// 参数: + /// - nodes: 节点列表,格式为 [{"host": "example.com", "port": 443}] + /// - concurrency: 并发数量 + /// - timeout: 超时时间(毫秒) + /// + /// 返回: + /// - 测试结果映射,键为 "host:port",值为延迟时间 + static Future> testMultipleNodes({ + required List> nodes, + int concurrency = 10, + int timeout = 5000, + }) async { + final results = {}; + final semaphore = Completer(); + var activeCount = 0; + var completedCount = 0; + + KRLogUtil.kr_i('🚀 开始批量延迟测试,共 ${nodes.length} 个节点,并发数: $concurrency', tag: 'KRLatencyTester'); + + Future processNode(MapEntry node) async { + try { + final host = node.value.address; + final port = node.value.port; + final key = node.key; + + final latency = await testNode( + host: host, + port: port, + timeout: timeout, + ); + + results[key] = latency; + } catch (e) { + results[node.key] = 65535; + KRLogUtil.kr_e('❌ 节点测试异常: ${node.key} - $e', tag: 'KRLatencyTester'); + } finally { + completedCount++; + activeCount--; + + if (completedCount >= nodes.length) { + semaphore.complete(); + } + } + } + + // 分批处理节点 + for (var i = 0; i < nodes.length; i += concurrency) { + final batch = nodes.skip(i).take(concurrency); + + for (final node in batch) { + activeCount++; + processNode(node); + } + + // 等待当前批次完成 + if (i + concurrency < nodes.length) { + await Future.delayed(Duration(milliseconds: 100)); + } + } + + // 等待所有任务完成 + await semaphore.future; + + KRLogUtil.kr_i('✅ 批量延迟测试完成,成功: ${results.length} 个', tag: 'KRLatencyTester'); + return results; + } +} + +/// Socket 地址类 +/// 表示网络地址和端口的组合 +class SocketAddress { + final String address; + final int port; + + SocketAddress(this.address, this.port); + + @override + String toString() => '$address:$port'; +} \ No newline at end of file