# Clash Meta 核心架构文档 ## 架构概览 LighthouseApp 使用 Clash Meta (Mihomo) 作为核心代理引擎,替代原有的 sing-box 实现。 ``` ┌─────────────────────────────────────────────────────────────┐ │ Flutter Application │ ├─────────────────────────────────────────────────────────────┤ │ Dart Layer │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ KRClashImp (lib/app/services/clash_imp/) │ │ │ │ • kr_clash_imp.dart - 核心封装 │ │ │ │ • clash_ffi.dart - FFI 绑定 │ │ │ │ • clash_config_generator - YAML 配置生成 │ │ │ │ • clash_service_handler - 服务处理器 │ │ │ └──────────────────┬───────────────────────────────────┘ │ │ │ dart:ffi │ ├─────────────────────┼───────────────────────────────────────┤ │ Android Native │ │ │ ┌──────────────────▼───────────────────────────────────┐ │ │ │ ClashService (Kotlin) │ │ │ │ • VPNService.kt - VPN 服务入口 │ │ │ │ • ClashService.kt - Clash 服务管理 │ │ │ │ • Service Isolate - 后台 Dart 运行时 │ │ │ └──────────────────┬───────────────────────────────────┘ │ │ │ JNI │ │ ┌──────────────────▼───────────────────────────────────┐ │ │ │ libclash.so (Go + C) │ │ │ │ • quickStart() - 启动核心 │ │ │ │ • getAndroidVpnOptions() - 获取 VPN 配置 │ │ │ │ • startTUN() - 启动 TUN 设备 │ │ │ │ • getTraffic() - 流量统计 │ │ │ └──────────────────┬───────────────────────────────────┘ │ │ │ │ ├─────────────────────┼───────────────────────────────────────┤ │ Go Core │ │ │ ┌──────────────────▼───────────────────────────────────┐ │ │ │ Clash.Meta (Mihomo) │ │ │ │ • TUN 设备管理 │ │ │ │ • 路由策略 (bypass-LAN) │ │ │ │ • 代理协议支持 (SS/Trojan/VMess/...) │ │ │ │ • DNS 解析 │ │ │ │ • 流量统计 │ │ │ └──────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` ## 核心组件 ### 1. Dart FFI 层 (`kr_clash_imp.dart`) **职责:** - 提供与 Go 核心的 FFI 通信接口 - 管理核心生命周期 (启动/停止) - 配置文件生成和管理 - 并发安全的初始化机制 **关键方法:** - `start()` - 启动 Clash 核心 - `stop()` - 停止核心 - `getAndroidVpnOptions()` - 获取 VPN 路由配置 (关键!) - `startTun()` - 启动 TUN 设备 **并发安全设计:** ```dart // 使用 Completer 实现初始化锁 Completer? _initLock; Future _ensureInitialized() async { if (_initialized) return; if (_initLock != null) { await _initLock!.future; // 等待其他初始化完成 return; } // 执行初始化... } ``` ### 2. Android Service 层 (`ClashService.kt`) **职责:** - 管理 VPN 服务生命周期 - 创建 Service Isolate (后台 Dart 运行时) - 处理系统 VPN 权限 - 注册底层网络回调 (修复模拟器兼容性) **Service Isolate 架构:** ```kotlin // 创建独立的 FlutterEngine 用于后台服务 serviceEngine = FlutterEngine(Application.application) // 执行 Dart Service 入口点 val entrypoint = DartExecutor.DartEntrypoint( FlutterInjector.instance().flutterLoader().findAppBundlePath(), "_clashService" // 在 lib/main.dart 中定义 ) serviceEngine?.dartExecutor?.executeDartEntrypoint(entrypoint) ``` ### 3. Go 核心层 (`core/`) **目录结构:** ``` core/ ├── Clash.Meta/ # Git 子模块,Mihomo 核心 ├── go.mod # Go 依赖管理 ├── lib_android.go # Android JNI 桥接 ├── action.go # 核心操作接口 └── hub.go # HTTP API 服务器 ``` **关键桥接函数:** ```go //export quickStart func quickStart(initParams, params, stateParams *C.char, port C.longlong) //export getAndroidVpnOptions func getAndroidVpnOptions() *C.char // 返回详细路由配置! //export startTUN func startTUN(fd C.int, callback unsafe.Pointer) C.int ``` ## 数据流 ### 启动流程 ``` 1. Flutter UI (用户点击连接) │ ├──> KRClashImp.start() │ ├─ 生成 Clash 配置 YAML │ ├─ 调用 FFI: quickStart() │ └─ 等待启动回调 │ ├──> libclash.so: quickStart() │ ├─ 初始化 Clash Meta 核心 │ ├─ 解析配置文件 │ └─ 启动监听器 │ ├──> ClashService.kt │ ├─ 调用 VpnService.prepare() │ ├─ 获取 VPN 权限 │ └─ 建立 TUN 接口 │ ├──> KRClashImp.getAndroidVpnOptions() ⭐ 关键! │ └─ 获取 35+ CIDR 路由列表 │ └──> VPNService.kt: 配置 VPN Builder ├─ addAddress("172.19.0.1/30") ├─ addRoute("0.0.0.0/1") ├─ addRoute("128.0.0.0/1") ├─ addRoute("10.0.0.0/8") # bypass-LAN └─ 启动 TUN 设备 ``` ### 流量统计流程 ``` 1. UI 定时器 (每秒) │ ├──> KRClashImp.getTraffic() │ └─ FFI 调用 │ ├──> libclash.so: getTraffic() │ └─ Clash Meta 内部统计 │ └──> 返回 JSON { "upload": 1234567, "download": 7654321 } ``` ## 关键设计决策 ### 为什么使用 Clash Meta 替代 sing-box? | 问题 | sing-box | Clash Meta | |------|----------|------------| | **Android VPN 路由** | 简单路由 (3-5条) | 详细路由 (35+条 CIDR) | | **bypass-LAN 支持** | ❌ 不支持 | ✅ 完整支持 | | **PermissionMonitor error 22** | ⚠️ 频繁出现 | ✅ 已解决 | | **模拟器兼容性** | ⚠️ 兼容性问题 | ✅ 完美兼容 | ### 并发安全保证 **问题:** Go 运行时初始化不是线程安全的,多个 Dart 方法并发调用 `_ensureInitialized()` 可能导致崩溃。 **解决方案:** 使用 `Completer` 实现初始化锁: ```dart // 场景 1: 第一次调用 Thread A: _ensureInitialized() → 创建 _initLock → 执行初始化 → complete() // 场景 2: 并发调用 Thread B: _ensureInitialized() → 发现 _initLock != null → await _initLock.future ✅ // 场景 3: 初始化失败重试 Thread C: _ensureInitialized() → 异常 → _initLock = null → 允许重试 ✅ ``` ## 配置文件 ### Clash 配置生成 (`clash_config_generator.dart`) ```yaml # 生成的 clash_config.yaml 示例 mixed-port: 51213 allow-lan: false tun: enable: true stack: system auto-route: true auto-detect-interface: true dns-hijack: - any:53 route-address: # ⭐ 关键! 35+ 详细路由 - 0.0.0.0/1 - 128.0.0.0/1 # ... bypass-LAN CIDRs route-exclude-address: - 10.0.0.0/8 # 绕过局域网 - 172.16.0.0/12 - 192.168.0.0/16 proxies: - name: "Server-1" type: ss server: example.com port: 8388 # ... proxy-groups: - name: "PROXY" type: select proxies: - Server-1 ``` ## 故障排查 参考 [CLASH_TROUBLESHOOTING.md](./CLASH_TROUBLESHOOTING.md) ## 构建指南 参考 [CLASH_BUILD_GUIDE.md](./CLASH_BUILD_GUIDE.md) ## 相关资源 - [Clash Meta 官方文档](https://wiki.metacubex.one/) - [Mihomo GitHub](https://github.com/MetaCubeX/mihomo) - [Xboard-Mihomo 参考实现](https://github.com/chen08209/Xboard-Mihomo)