177 lines
5.8 KiB
Markdown
Executable File
177 lines
5.8 KiB
Markdown
Executable File
# 延迟测试逻辑确认
|
||
|
||
## 🎯 需求确认
|
||
|
||
**用户需求**:
|
||
- **连接代理时**: 保持默认测试规则(使用 SingBox 通过代理测试)
|
||
- **没连接时**: 使用本地网络的ping(直接连接节点IP)
|
||
|
||
## 📋 当前实现逻辑
|
||
|
||
### **1. 连接状态判断**
|
||
|
||
#### **连接状态变量**: `kr_isConnected`
|
||
```dart
|
||
// 是否已连接
|
||
final kr_isConnected = false.obs;
|
||
```
|
||
|
||
#### **连接状态更新逻辑**: `_bindConnectionStatus()`
|
||
```dart
|
||
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()`
|
||
```dart
|
||
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()`
|
||
```dart
|
||
/// 未连接状态下的延迟测试(使用本机网络直接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()`
|
||
```dart
|
||
/// 测试单个节点的延迟(使用本机网络直接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)**:
|
||
1. **使用默认测试规则**: 调用 `KRSingBoxImp.instance.kr_urlTest("select")`
|
||
2. **通过代理测试**: 使用 SingBox 的 URL 测试功能
|
||
3. **等待测试完成**: 等待3秒让 SingBox 完成测试
|
||
4. **获取测试结果**: 从 `KRSingBoxImp.instance.kr_activeGroups` 获取延迟信息
|
||
|
||
### **没连接时(kr_isConnected.value = false)**:
|
||
1. **使用本机网络**: 调用 `_kr_testLatencyWithoutVpn()`
|
||
2. **直接连接节点**: 使用 `Socket.connect()` 直接连接节点IP
|
||
3. **绕过代理**: 不经过任何代理,使用本机网络
|
||
4. **并行测试**: 同时测试所有节点,提高效率
|
||
5. **真实延迟**: 获得本机到节点的真实网络延迟
|
||
|
||
## 🔍 关键判断点
|
||
|
||
### **连接状态判断**:
|
||
```dart
|
||
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()` 直接连接节点
|
||
|
||
## 📝 总结
|
||
|
||
**✅ 当前实现完全符合用户需求**:
|
||
|
||
1. **连接代理时**: 保持默认测试规则,使用 SingBox 通过代理测试延迟
|
||
2. **没连接时**: 使用本机网络直接ping节点IP,绕过代理获取真实延迟
|
||
|
||
**🔧 实现特点**:
|
||
- 自动根据连接状态选择测试方式
|
||
- 连接时使用代理测试,未连接时使用直连测试
|
||
- 详细的日志记录,便于调试和验证
|
||
- 并行测试提高效率
|
||
- 完善的错误处理和超时机制
|
||
|
||
**🎯 用户需求已完全实现!**
|