Netcatty Android 开发文档

Netcatty Android 开发文档:涵盖技术选型、项目结构、核心模块开发指南、数据模型、UI 规范、构建环境、测试策略及已知约束。

一、项目概述

Netcatty Android 是桌面端 Netcatty 的移动端版本,面向需要在移动设备上管理远程服务器的开发者、运维工程师和 DevOps 人员。

核心价值:移动端 SSH 终端 + SFTP 文件管理 + AI 辅助运维 + 云端多设备同步配置

功能范围

功能 优先级 Phase
SSH 连接 + 终端 P0 1
主机管理 (Vault) P0 1
密码/密钥认证 P0 1
SFTP 文件浏览 P0 2
文件上传/下载 P0 2
分屏终端 P1 3
端口转发 P1 3
快捷命令 (Snippet) P1 3
加密存储 + 生物识别 P1 4
云同步 P2 4
AI Chat P2 5
串口连接 P3 6

非目标 (Out of Scope)

  • 本地终端 (Android 无 PTY)
  • Mosh 协议 (Phase 6 考虑)
  • Monaco 代码编辑器 (使用轻量替代)
  • Electron 特有功能 (系统托盘、全局快捷键等)

二、技术选型详述

2.1 SSH 库: JSch

对比项 JSch 0.2.x Kotlin-ssh2 Apache MINA SSHD
纯 Java/Kotlin
Android 兼容 ✅ 成熟 🟡 较新 🟡 较重
SFTP 支持
密钥格式支持 ✅ (OpenSSH/PuTTY/PKCS8) 🟡
体积 ~300KB ~200KB ~2MB+
sbssh 项目验证

2.2 终端渲染: Termux terminal-emulator

  • 处理 ESC 序列解析、字符渲染、滚动、选区
  • 支持自定义配色方案
  • Compose 通过 AndroidView 嵌入

2.3 数据存储: Room + 字段级 AES-GCM 加密

  • Room 作为本地数据库(SQLite)
  • AES-GCM 字段级加密敏感字段(密码、私钥)
  • PBKDF2 从用户密码派生会话密钥
  • Android Keystore 存储 PBKDF2 salt + 密钥哈希

2.4 依赖注入: Hilt

标准 Google 推荐方案,编译期检查,与 Compose 深度集成。

三、项目结构

netcatty-android/
├── app/src/main/java/com/netcatty/mobile/
│   ├── NetcattyApp.kt                    # Application
│   ├── MainActivity.kt                    # 单 Activity
│   ├── di/                                # Hilt Modules
│   ├── data/
│   │   ├── local/                         # Room DAO + Entity
│   │   ├── remote/                        # JSch SSH + SFTP
│   │   ├── ai/                            # Retrofit AI API
│   │   ├── sync/                          # 云同步适配器
│   │   └── crypto/                        # FieldCryptoManager
│   ├── domain/
│   │   ├── model/                         # 数据模型
│   │   ├── repository/                    # 仓库接口
│   │   └── usecase/                       # 业务逻辑
│   ├── ui/
│   │   ├── screens/                       # 页面 (Vault/Terminal/SFTP/Settings/AI)
│   │   ├── components/                    # 共享组件
│   │   └── theme/                         # 主题 + 配色
│   └── service/                           # 前台服务
└── build.gradle.kts

四、核心模块开发指南

4.1 SSH 连接管理

SshSessionManager 负责管理所有活跃 SSH 会话:

@Singleton
class SshSessionManager @Inject constructor(
    private val fieldCryptoManager: FieldCryptoManager
) {
    private val sessions = ConcurrentHashMap<String, SshConnection>()
    private val jsch = JSch()

    suspend fun connect(host: Host): Result<TerminalSession>
    fun writeToSession(sessionId: String, data: String)
    fun resizeSession(sessionId: String, cols: Int, rows: Int)
    fun disconnect(sessionId: String)
    fun getSession(sessionId: String): SshConnection?
    fun disconnectAll()
}

认证策略:密码 → 密钥 → 键盘交互式(2FA/MFA),与桌面端 sshAuthHelper.cjs 对齐。

4.2 终端渲染

桥接 JSch Channel 和 Termux TerminalSession:

class NetcattyTerminalSession(
    private val connection: SshConnection
) {
    // JSch InputStream → TerminalSession (读取远端输出)
    // TerminalView 输入 → SshConnection.write() (发送用户输入)
    fun write(data: String)
    fun resize(cols: Int, rows: Int)
}

Compose 嵌入方式:AndroidView(factory = { TerminalView(it) })

4.3 SFTP 文件管理

class SftpClient(private val session: Session) {
    fun connect(): ChannelSftp
    fun listDirectory(path: String): List<SftpFileEntry>
    fun download(remotePath: String, localPath: String, monitor: SftpProgressMonitor?)
    fun upload(localPath: String, remotePath: String, monitor: SftpProgressMonitor?)
    fun disconnect()
}

4.4 端口转发

class PortForwardingManager @Inject constructor(
    private val sshSessionManager: SshSessionManager
) {
    suspend fun startForward(rule: PortForwardingRule): Result<Tunnel>
    suspend fun stopForward(tunnelId: String)
    fun getActiveTunnels(): List<Tunnel>
}

4.5 AI Chat 服务

class AiChatService @Inject constructor(
    private val okHttpClient: OkHttpClient
) {
    suspend fun streamChat(
        provider: AiProvider,
        messages: List<ChatMessage>,
        onChunk: (String) -> Unit
    ): Flow<String>
}

五、数据模型

Host (对应桌面端 Host)

data class Host(
    val id: String,
    val label: String,
    val hostname: String,
    val port: Int = 22,
    val username: String,
    val authMethod: AuthMethod = AuthMethod.PASSWORD,
    val passwordEncrypted: String? = null,    // AES-GCM 加密
    val identityFileId: String? = null,
    val group: String? = null,
    val tags: List<String> = emptyList(),
    val protocol: HostProtocol = HostProtocol.SSH,
    val keepaliveInterval: Int = 0,
    val pinned: Boolean = false,
    // ...更多字段与桌面端对齐
)

SshKey / Snippet / PortForwardingRule / TerminalTheme

所有数据模型字段与桌面端 domain/models.ts 一一对齐,确保云同步兼容。

六、UI/UX 设计规范

导航结构

Bottom Navigation: Vault | Terminal | SFTP | Settings

移动端特殊交互

交互 实现方式
终端输入 底部浮动输入栏 + 特殊键行 (Tab/Ctrl/Esc/↑↓)
复制粘贴 长按选区 → 弹出菜单
分屏 仅横屏支持
SFTP 操作 长按文件/文件夹 → Context Menu
AI Chat 终端侧边抽屉

七、构建环境

  • JDK: 21
  • Android SDK: API 34+ (platforms-34, build-tools-34.0.0)
  • Kotlin: 2.0.21+
  • Gradle: 8.11+
  • Min SDK: 26 (Android 8.0)
  • Target SDK: 35
  • 所有 build.gradle.kts 必须配置阿里云 Maven 镜像

八、开发路线图

Phase 时间 里程碑
0 第 1 周 项目搭建
1 第 2-5 周 核心 SSH
2 第 6-8 周 SFTP
3 第 9-11 周 高级终端
4 第 12-13 周 安全+云同步
5 第 14-15 周 AI
6 第 16-17 周 发布准备

九、测试策略

模块 测试框架 覆盖重点
Domain Model JUnit 5 数据模型转换、同步合并逻辑
Repository JUnit 5 + MockK CRUD 操作、加密/解密流程
SSH Session Robolectric 连接/断开/重连逻辑
AI Service MockWebServer SSE 流式响应解析
UI Compose Test 关键路径 E2E

十、已知约束

  • Android 沙箱限制:无法 fork 子进程,不能运行本地 shell
  • 后台限制:Android 12+ 对前台服务限制更严
  • JSch 注意:不原生支持 Ed25519 密钥的 PuTTY PPK 格式
  • 软键盘:弹出时需调整终端区域高度
  • i18n:移动端特有字符串需额外翻译

十一、许可证

Netcatty 原项目使用 GPL-3.0 许可证。Android 版本同样必须使用 GPL-3.0-or-later 开源。


本文由博客助手大龙虾整理。