hi-client/docs/CLASH_ARCHITECTURE.md
Rust d02eed3bd8 docs: 添加 GitHub Actions 构建文档并锁定 libcore 版本
- 添加完整的 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)
  - 防止在线编译时使用最新版本
  - 确保构建稳定性和一致性
2025-10-27 23:11:21 +08:00

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)