🔍 debug: 添加详细诊断日志以追踪节点切换失败问题

问题现象:
- 用户从韩国节点切换到日本节点
- UI 显示已切换到日本
- 但实际流量仍从韩国节点出去

诊断目标:
1. 验证目标节点是否在 SingBox 活动组中存在
2. 追踪 selectOutbound() 是否真正被调用
3. 确认节点标签 (tag) 的匹配情况

修改内容:

1. kr_home_controller.dart (kr_performNodeSwitch 方法):
   - 在调用 kr_selectOutbound 之前,列出所有活动组和节点
   - 检查目标节点是否存在于活动组中
   - 打印调用前后的关键日志

2. kr_sing_box_imp.dart (kr_selectOutbound 方法):
   - 搜索目标节点是否在活动组中存在
   - 如果找不到,打印所有可用的节点列表
   - 添加 selectOutbound API 调用的详细日志

日志输出示例:
 在组 "select" 中找到目标节点: Japan-Tokyo
 调用 selectOutbound("select", "Japan-Tokyo")...
 节点切换完成: Japan-Tokyo

或

⚠️ 未能在任何活动组中找到目标节点: Japan-Tokyo
  可用节点: Korea-Seoul
  可用节点: USA-NewYork
  ...

验证:
 编译通过(仅有之前存在的警告)
 无新增编译错误

下一步:
- 运行此版本并获取用户的日志输出
- 根据日志结果定位真正的原因
- 实施正式修复

(cherry picked from commit 40ff4cc2654c6c1fd939a157483f94872ecbda73)
This commit is contained in:
Rust 2025-10-31 22:22:58 +08:00 committed by speakeloudest
parent 16a1ed789e
commit 7083369cd4
2 changed files with 37 additions and 0 deletions

View File

@ -1156,12 +1156,25 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
try {
KRLogUtil.kr_i('🔌 VPN已连接开始切换后台节点: $tag', tag: 'HomeController');
// 🔧
KRLogUtil.kr_i('📊 当前活动组数量: ${KRSingBoxImp.instance.kr_activeGroups.length}', tag: 'HomeController');
for (var group in KRSingBoxImp.instance.kr_activeGroups) {
KRLogUtil.kr_i('📋 活动组: tag=${group.tag}, type=${group.type}, 节点数=${group.items.length}', tag: 'HomeController');
for (var item in group.items) {
if (item.tag == tag) {
KRLogUtil.kr_i('✅ 找到目标节点: ${item.tag}', tag: 'HomeController');
}
}
}
// 🔧 VPN已连接时-1"正在连接"
kr_currentNodeLatency.value = -1;
kr_isLatency.value = true; //
//
KRLogUtil.kr_i('⏳ 调用 kr_selectOutbound($tag),等待完成...', tag: 'HomeController');
await KRSingBoxImp.instance.kr_selectOutbound(tag);
KRLogUtil.kr_i('✅ kr_selectOutbound 完成,开始更新 UI', tag: 'HomeController');
// UI
kr_cutSeletedTag.value = tag;

View File

@ -1306,6 +1306,29 @@ class KRSingBoxImp {
KRLogUtil.kr_i('🎯 [v2.1] 开始选择出站节点: $tag', tag: 'SingBox');
KRLogUtil.kr_i('📊 当前活动组数量: ${kr_activeGroups.length}', tag: 'SingBox');
// 🔧
KRLogUtil.kr_i('🔍 搜索目标节点 "$tag" 在活动组中...', tag: 'SingBox');
bool foundNode = false;
for (var group in kr_activeGroups) {
for (var item in group.items) {
if (item.tag == tag) {
foundNode = true;
KRLogUtil.kr_i('✅ 在组 "${group.tag}" 中找到目标节点: $tag', tag: 'SingBox');
break;
}
}
if (foundNode) break;
}
if (!foundNode) {
KRLogUtil.kr_w('⚠️ 未能在任何活动组中找到目标节点: $tag', tag: 'SingBox');
//
for (var group in kr_activeGroups) {
for (var item in group.items) {
KRLogUtil.kr_d(' 可用节点: ${item.tag}', tag: 'SingBox');
}
}
}
// 🔧 使 await
try {
await KRSecureStorage().kr_saveData(key: _keySelectedNode, value: tag);
@ -1320,6 +1343,7 @@ class KRSingBoxImp {
KRLogUtil.kr_i('✅ Command client 已就绪,执行节点切换', tag: 'SingBox');
// 🔧 使 await
KRLogUtil.kr_i('⏳ 调用 selectOutbound("select", "$tag")...', tag: 'SingBox');
await _kr_selectOutboundWithRetry("select", tag, maxAttempts: 3, initialDelay: 50);
KRLogUtil.kr_i('✅ 节点切换完成: $tag', tag: 'SingBox');
} catch (e) {