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

9.6 KiB

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 设备

并发安全设计:

// 使用 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 架构:

// 创建独立的 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 服务器

关键桥接函数:

//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 实现初始化锁:

// 场景 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)

# 生成的 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_BUILD_GUIDE.md

相关资源