跳转到内容

系统架构

NetShuttle 采用“共享业务层 + 平台适配层”。共享核心保留在 Core、Models、Engine、Storage 和 Managers,不为了目录整齐进行大规模搬迁。

NetShuttleApp(条件编译入口)
├── macOS: MenuBarExtra / Settings / Help / TTY CLI
└── iOS / iPadOS: WindowGroup / AdaptiveMainView
Shared
├── ServiceContainer / ServiceProtocols
├── SSHEngine / PortForwardingManager / ProxyJumpHandler
├── SSHConnectionManager / AutoReconnectManager / NetworkMonitor
├── StorageProvider / Local / iCloud / DataMigrator
└── ShellSession / ShellSessionManager / SSHShellSessionManager
Models
├── SSHServerConfiguration
├── TunnelConfiguration
├── PortForwardRule
├── AuthMethod
└── ForwardingMode
UI and Platform
├── ViewModels
├── Shared Views
├── macOS AppKit / MenuBarExtra
└── iOS UIKit / SwiftTerm / Adaptive Navigation

ServiceContainer 是单例 DI 容器,集中持有连接、网络、速率与自动重连服务。测试可以通过 override* 注入 Mock,resetToDefaults() 恢复默认实现。

这层边界的目的是让网络状态、重连计时器和存储迁移不直接嵌入 SwiftUI View,也不会把 NIO Channel 或 EventLoop 带入 UI 状态。

所有 SSH 连接复用 SSHConnectionManager 持有的单线程 MultiThreadedEventLoopGroup。连接数量增加时,不额外创建独立线程池。

  • Local、iCloud Provider 和 DataMigrator 使用 actor 隔离可变状态。
  • 跨执行器接口使用 async throws 和 Sendable。
  • 项目启用 Complete Strict Concurrency Checking,不使用 @unchecked Sendable 绕过检查。
  • SSH Channel 仅在对应 EventLoop 上操作;跨线程共享的可变状态必须加锁或串行化。
  • SwiftUI 状态层使用 @MainActor,不持有 NIO Channel 或 EventLoop。

TerminalLaunching 隔离业务层与平台终端:

  • macOS:LocalTerminalManager + Unix Socket TTY Bridge + 外部终端 CLI。
  • iOS / iPadOS:MobileTerminalLauncher + SwiftTerm 直接附加 ShellSession。

两条路径共享 Shell 生命周期,但不共享传输和展示适配层。

  1. 使用 SwiftNIO SSH,避免管理外部 SSH 进程。
  2. 每条转发规则独立管理,保证独立启停。
  3. 用户断开与意外断开分开记录。
  4. 配置、Secret 和日志有明确同步边界。
  5. 终端品牌不进入 Swift 分支,由 JSON Profile 和通用启动策略描述。