5.8 KiB
Executable File
5.8 KiB
Executable File
延迟测试逻辑确认
🎯 需求确认
用户需求:
- 连接代理时: 保持默认测试规则(使用 SingBox 通过代理测试)
- 没连接时: 使用本地网络的ping(直接连接节点IP)
📋 当前实现逻辑
1. 连接状态判断
连接状态变量: kr_isConnected
// 是否已连接
final kr_isConnected = false.obs;
连接状态更新逻辑: _bindConnectionStatus()
void _bindConnectionStatus() {
ever(KRSingBoxImp.instance.kr_status, (status) {
switch (status) {
case SingboxStopped():
kr_isConnected.value = false; // 未连接
break;
case SingboxStarting():
kr_isConnected.value = true; // 连接中
break;
case SingboxStarted():
kr_isConnected.value = true; // 已连接
break;
case SingboxStopping():
kr_isConnected.value = false; // 断开中
break;
}
});
}
2. 延迟测试逻辑
主测试方法: kr_urlTest()
Future<void> kr_urlTest() async {
KRLogUtil.kr_i('📊 当前连接状态: ${kr_isConnected.value}', tag: 'HomeController');
if (kr_isConnected.value) {
// ✅ 已连接状态:使用 SingBox 通过代理测试(默认测试规则)
KRLogUtil.kr_i('🔗 已连接状态 - 使用 SingBox 通过代理测试延迟', tag: 'HomeController');
await KRSingBoxImp.instance.kr_urlTest("select");
// 等待 SingBox 完成测试
await Future.delayed(const Duration(seconds: 3));
// 检查活动组状态
final activeGroups = KRSingBoxImp.instance.kr_activeGroups;
// ... 处理测试结果
} else {
// ✅ 未连接状态:使用本机网络直接ping节点IP
KRLogUtil.kr_i('🔌 未连接状态 - 使用本机网络直接ping节点IP测试延迟', tag: 'HomeController');
KRLogUtil.kr_i('🌐 这将绕过代理,直接使用本机网络连接节点', tag: 'HomeController');
await _kr_testLatencyWithoutVpn();
}
}
3. 本机网络测试逻辑
本机网络测试方法: _kr_testLatencyWithoutVpn()
/// 未连接状态下的延迟测试(使用本机网络直接ping节点IP)
Future<void> _kr_testLatencyWithoutVpn() async {
KRLogUtil.kr_i('🔌 开始未连接状态延迟测试(使用本机网络)', tag: 'HomeController');
KRLogUtil.kr_i('🌐 将使用本机网络直接连接节点IP进行延迟测试', tag: 'HomeController');
// 获取所有非auto节点
final testableNodes = kr_subscribeService.allList
.where((item) => item.tag != 'auto')
.toList();
// 并行执行所有测试任务
final testTasks = testableNodes
.map((item) => _kr_testSingleNode(item))
.toList();
await Future.wait(testTasks);
// 统计和显示测试结果
// ...
}
单个节点测试方法: _kr_testSingleNode()
/// 测试单个节点的延迟(使用本机网络直接ping节点IP)
Future<void> _kr_testSingleNode(dynamic item) async {
KRLogUtil.kr_i('🔌 使用本机网络直接连接测试(绕过代理)', tag: 'NodeTest');
// 使用本机网络直接连接测试节点延迟
final socket = await Socket.connect(
address,
port,
timeout: const Duration(seconds: 8), // 8秒超时
);
// 获取延迟时间
final delay = stopwatch.elapsedMilliseconds;
// 设置延迟阈值:超过5秒认为节点不可用
if (delay > 5000) {
item.urlTestDelay.value = 65535; // 标记为不可用
} else {
item.urlTestDelay.value = delay; // 使用本机网络测试的延迟结果
}
}
✅ 逻辑确认
连接代理时(kr_isConnected.value = true):
- 使用默认测试规则: 调用
KRSingBoxImp.instance.kr_urlTest("select") - 通过代理测试: 使用 SingBox 的 URL 测试功能
- 等待测试完成: 等待3秒让 SingBox 完成测试
- 获取测试结果: 从
KRSingBoxImp.instance.kr_activeGroups获取延迟信息
没连接时(kr_isConnected.value = false):
- 使用本机网络: 调用
_kr_testLatencyWithoutVpn() - 直接连接节点: 使用
Socket.connect()直接连接节点IP - 绕过代理: 不经过任何代理,使用本机网络
- 并行测试: 同时测试所有节点,提高效率
- 真实延迟: 获得本机到节点的真实网络延迟
🔍 关键判断点
连接状态判断:
if (kr_isConnected.value) {
// 连接代理时:使用 SingBox 默认测试规则
} else {
// 没连接时:使用本机网络直接ping节点IP
}
连接状态来源:
kr_isConnected的值来自KRSingBoxImp.instance.kr_status- 当 SingBox 状态为
SingboxStarted()或SingboxStarting()时,kr_isConnected = true - 当 SingBox 状态为
SingboxStopped()或SingboxStopping()时,kr_isConnected = false
📊 测试验证
测试场景1: 连接代理时
- 预期行为: 使用 SingBox 通过代理测试
- 验证日志:
🔗 已连接状态 - 使用 SingBox 通过代理测试延迟 - 测试方式:
KRSingBoxImp.instance.kr_urlTest("select")
测试场景2: 没连接时
- 预期行为: 使用本机网络直接ping节点IP
- 验证日志:
🔌 未连接状态 - 使用本机网络直接ping节点IP测试延迟 - 测试方式:
Socket.connect()直接连接节点
📝 总结
✅ 当前实现完全符合用户需求:
- 连接代理时: 保持默认测试规则,使用 SingBox 通过代理测试延迟
- 没连接时: 使用本机网络直接ping节点IP,绕过代理获取真实延迟
🔧 实现特点:
- 自动根据连接状态选择测试方式
- 连接时使用代理测试,未连接时使用直连测试
- 详细的日志记录,便于调试和验证
- 并行测试提高效率
- 完善的错误处理和超时机制
🎯 用户需求已完全实现!