- 添加完整的 GitHub Actions 构建指南文档 - BUILD_GUIDE.md: Android 详细构建指南 - MULTIPLATFORM_GUIDE.md: 多平台构建指南 - HOW_TO_BUILD.md: 分步操作教程 - QUICKSTART.md: 3步快速开始指南 - INDEX.md: 文档总览索引 - README.md: 基础说明 - 创建 docs/ 目录存放项目文档 - 锁定 libcore 子模块到 f993a57 (v3.1.7) - 防止在线编译时使用最新版本 - 确保构建稳定性和一致性
256 lines
9.6 KiB
Markdown
256 lines
9.6 KiB
Markdown
# 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<void>? _initLock;
|
|
|
|
Future<void> _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)
|