# Core 模块重构完成报告 - Phase 1

## ✅ 已完成（Phase 1: 目录结构调整）

### 1. 清理重复代码
- ✅ 删除 `core/transport/connect/` - 重复的 connect 包
- ✅ 删除 `core/transport/intercept.go` - 废弃文件

### 2. 创建 client/ 目录
- ✅ 新建 `core/client/` 目录
- ✅ 移动 `stun_client.go` → `core/client/stun_client.go`
- ✅ 移动 `turn_client.go` → `core/client/turn_client.go`
- ✅ 移动 `websocket_client.go` → `core/client/ws_client.go`
- ✅ 更新所有文件的 package 声明为 `package client`

### 3. 重命名 connect/ 文件
- ✅ `turn_factory.go` → `turn_udp.go` (TURN-UDP 工厂)
- ✅ `ws_factory.go` → `ws.go` (WS/WSS 工厂)
- ✅ `turn_quic.go` 保持不变 (TURN-QUIC 工厂)

---

## 📋 当前目录结构

```
core/
├── client/                    # ✅ 协议客户端（不返回连接）
│   ├── stun_client.go         # STUN 协议：Binding/NAT 检测
│   ├── turn_client.go         # TURN 协议：Allocate/Permission
│   └── ws_client.go           # WebSocket 协议：Handshake/Frame
│
├── connect/                   # ✅ 建连工厂（返回 net.Conn）
│   ├── strategy.go            # 9 层策略调度
│   ├── ice.go                 # ICE 协商 + WebRTC
│   ├── fake_tcp.go            # FakeTCP 工厂
│   ├── real_tcp.go            # RealTCP 工厂
│   ├── turn_udp.go            # TURN-UDP 工厂 ✅ 已重命名
│   ├── turn_quic.go           # TURN-QUIC 工厂
│   ├── ws.go                  # WS/WSS 工厂 ✅ 已重命名
│   └── stun.go                # Direct-UDP 工厂（包含 STUN 探测）
│
├── transport/                 # ✅ 传输绑定层（WireGuard 数据传输）
│   ├── core_bind.go           # conn.Bind 实现
│   └── relay.go               # Read/Write 循环
│
├── connection_manager.go      # Peer 连接管理
├── core.go                    # Core 主实例
└── core_service_server.go     # gRPC 服务
```

---

## ⏳ 待完成（Phase 2: 消除重复代码）

### 问题：connect/ 中有重复的客户端实现

#### 1. STUN 客户端重复

**`connect/stun.go`**:
```go
type STUNClient struct {
    servers []string
    logger  *zap.Logger
}

func NewSTUNClient(servers []string, logger *zap.Logger) *STUNClient
func (c *STUNClient) GetExternalAddress(ctx context.Context) (net.Addr, error)
```

**`client/stun_client.go`**:
```go
type STUNClient struct {
    servers           []string
    logger            *zap.Logger
    timeout           time.Duration
    selectionStrategy string
}

func NewSTUNClient(servers []string, logger *zap.Logger) *STUNClient
func (c *STUNClient) GetExternalAddress(ctx context.Context) (net.Addr, error)
func (c *STUNClient) DetectNATType() NATType
```

**解决方案**：
- ❌ 删除 `connect/stun.go` 中的 `STUNClient` 实现
- ✅ 改为调用 `client/stun_client.go`
- ✅ `connect/stun.go` 只保留 `P2PFactory.Dial()` 逻辑

---

#### 2. TURN 客户端重复

**`connect/turn_udp.go`**:
```go
type TURNClient struct {
    protocol TURNProtocol
    servers  []string
    logger   *zap.Logger
}

func NewTURNClient(protocol TURNProtocol, servers []string, logger *zap.Logger) *TURNClient
func (c *TURNClient) Allocate(ctx context.Context, peerAddr net.Addr) (net.Conn, error)
```

**`client/turn_client.go`**:
```go
type TURNClient struct {
    servers    []TURNServer
    username   string
    password   string
    credential string
    authType   TURNAuthType
    realm      string
    logger     *zap.Logger
}

func NewTURNClient(servers []TURNServer, username, password string, logger *zap.Logger) *TURNClient
func (c *TURNClient) Allocate(ctx context.Context, peerAddr net.Addr) (net.Conn, error)
```

**解决方案**：
- ❌ 删除 `connect/turn_udp.go` 中的 `TURNClient` 实现
- ✅ 改为调用 `client/turn_client.go`
- ✅ `connect/turn_udp.go` 只保留 `TURNFactory.Dial()` 逻辑

---

## 🔧 Phase 2 重构步骤

### Step 1: 重构 connect/stun.go

**修改前**：
```go
// connect/stun.go
type STUNClient struct { ... }  // 重复实现

func (f *P2PFactory) Dial(ctx context.Context, config *DialConfig) (net.Conn, error) {
    // 直接使用自己的 STUNClient
}
```

**修改后**：
```go
// connect/stun.go
import "git.zkcoi.com/zkcoi/meshray/core/client"

func (f *P2PFactory) Dial(ctx context.Context, config *DialConfig) (net.Conn, error) {
    // 1. 调用 client/stun_client.go
    stun := client.NewSTUNClient(stunServers, f.logger)
    
    // 2. 获取外部地址
    addr, err := stun.GetExternalAddress(ctx)
    
    // 3. 尝试直连
    conn, err := net.DialUDP("udp4", nil, addr)
    
    // 4. 包装成 net.Conn 返回
    return NewDirectUDPConn(conn), nil
}
```

### Step 2: 重构 connect/turn_udp.go

类似地，改为调用 `client/turn_client.go`。

---

## 📊 重构收益

| 维度 | 重构前 | 重构后 | 改进 |
|------|--------|--------|------|
| **职责清晰度** | ❌ connect 和 client 职责混淆 | ✅ connect 管决策，client 管协议 | ⭐⭐⭐⭐⭐ |
| **代码复用** | ❌ STUN/TURN 重复实现 | ✅ 单一实现，多处调用 | ⭐⭐⭐⭐⭐ |
| **可维护性** | ❌ 修改一处要改多处 | ✅ 修改只在 client 层 | ⭐⭐⭐⭐⭐ |
| **可扩展性** | ❌ 新增协议要改多处 | ✅ 新增协议只在 client 层 | ⭐⭐⭐⭐⭐ |

---

## 🎯 下一步行动

### 立即执行
1. **验证编译**：检查当前状态是否编译通过
2. **修复引用**：更新所有 import 路径

### 近期完成
3. **消除重复**：重构 `connect/stun.go` 和 `connect/turn_udp.go`
4. **补充缺失**：创建 `direct_udp.go`、`turn_tcp.go`、`turn_tls.go`

### 后续迭代
5. **完善文档**：更新 README 中的目录结构说明
6. **添加测试**：为每个 client 添加单元测试

---

*创建时间：2026-03-24 00:25*  
*版本：v2.1.0*  
*Phase 1: ✅ 完成 | Phase 2: ⏳ 进行中*
