# EasyRemote - 远程桌面控制软件

EasyRemote 是一个基于 Rust 开发的远程桌面控制软件，支持 P2P 直连和服务器中转两种连接方式，提供高性能的远程控制体验。

## ✨ 功能特性

### 客户端功能
- 🔐 **设备ID + 验证码** 连接方式，类似 TeamViewer/向日葵
- 👥 **账号登录** 支持，同步设备列表和控制历史
- 🖥️ **高性能屏幕捕获**，支持多显示器
- ⌨️ **完整输入控制**，包括鼠标、键盘、滚轮
- 📋 **剪贴板同步**
- 📊 **控制历史记录**
- ⚙️ **质量设置**，可调节帧率、分辨率、图像质量

### 服务端功能
- 🌐 **Web 管理后台**，管理用户、设备、会话
- 📡 **信令服务器**，支持 WebSocket
- 🔄 **P2P 穿透**，优先直连，备选中转
- 🛰️ **内置 STUN 服务器**，支持 NAT 穿透
- 👮 **管理员功能**：强制下线、结束会话
- 🖥️ **浏览器远程控制**（管理员）

### 技术特点
- 🦀 **纯 Rust 实现**，高性能、内存安全
- 🔒 **端到端加密**，AES-256-GCM
- 🚀 **P2P 优先**，低延迟
- 📦 **跨平台**，支持 Windows、macOS、Linux

## 🏗️ 项目结构

```
easyremote/
├── Cargo.toml                 # Workspace 配置
├── crates/
│   ├── common/                # 共享库（协议、类型、加密）
│   ├── server/                # 服务端
│   │   └── static/            # Web 管理后台
│   ├── client-core/           # 客户端核心（屏幕捕获、输入控制）
│   └── client-tauri/          # Tauri 桌面客户端
│       └── ui/                # Vue3 前端
└── README.md
```

## 🚀 快速开始

### 环境要求

- Rust 1.70+
- Node.js 18+ (客户端前端)
- SQLite (服务端数据库)

### 构建服务端 (Windows)

```bash
# 编译服务端
cargo build --release -p easyremote-server

# 运行服务端
.\target\release\easyremote-server.exe
```

服务端默认运行在 `http://localhost:8080`，管理后台访问 `http://localhost:8080/`

### 构建服务端 (Linux)

**方式一：直接在 Linux 上构建**
```bash
# 克隆项目
git clone https://github.com/your-repo/easyremote.git
cd easyremote

# 运行构建脚本
chmod +x scripts/build-linux.sh
./scripts/build-linux.sh

# 启动服务
./release/linux/start.sh
```

**方式二：使用 Docker**
```bash
# 使用 docker-compose 一键部署
docker-compose up -d

# 或者手动构建和运行
docker build -f Dockerfile.server -t easyremote-server .
docker run -d -p 8080:8080 -p 3478:3478/udp --name easyremote easyremote-server
```

**方式三：使用 systemd 服务**
```bash
# 复制文件到 /opt/easyremote
sudo mkdir -p /opt/easyremote
sudo cp -r release/linux/* /opt/easyremote/

# 安装 systemd 服务
sudo cp /opt/easyremote/easyremote.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable easyremote
sudo systemctl start easyremote

# 查看状态
sudo systemctl status easyremote
```

### 构建客户端

```bash
# 进入客户端目录
cd crates/client-tauri

# 安装前端依赖
cd ui && npm install && cd ..

# 开发模式运行
cargo tauri dev

# 构建发布版本
cargo tauri build
```

## ⚙️ 配置

### 服务端配置

创建 `.env` 文件：

```env
# 服务器配置
HOST=0.0.0.0
PORT=8080

# STUN 服务器配置
STUN_PORT=3478                    # STUN 服务端口（UDP）
ENABLE_LOCAL_STUN=true            # 启用内置 STUN 服务
# PUBLIC_IP=your.public.ip        # 公网 IP（可选，用于生成正确的 STUN URL）

# 额外的 STUN 服务器（可选，会添加到本地 STUN 后面）
# STUN_SERVERS=stun:stun.l.google.com:19302

# 数据库配置
DATABASE_URL=sqlite:easyremote.db?mode=rwc

# JWT 配置
JWT_SECRET=your-super-secret-jwt-key-change-in-production
JWT_EXPIRY=86400

# TURN 服务器（可选，用于无法 P2P 直连时中转）
# TURN_SERVER=turn:your-turn-server:3478
# TURN_USERNAME=username
# TURN_PASSWORD=password
```

### STUN 服务说明

EasyRemote 服务端内置了 STUN (Session Traversal Utilities for NAT) 服务器，用于帮助客户端发现其公网 IP 地址，实现 P2P 穿透连接。

**配置说明：**
- `ENABLE_LOCAL_STUN=true`：启用本地 STUN 服务（默认开启）
- `STUN_PORT=3478`：STUN 服务监听的 UDP 端口（默认 3478，标准端口）
- `PUBLIC_IP`：如果服务器有公网 IP，设置此项可让客户端正确连接

**防火墙配置：**
如果使用防火墙，需要开放以下端口：
- TCP 8080：HTTP/WebSocket 服务
- UDP 3478：STUN 服务

**客户端获取 ICE 配置：**
客户端可以通过 API 获取 ICE 服务器配置：
```bash
curl http://localhost:8080/api/ice-servers
# 返回：{"stun_servers":["stun:localhost:3478"],"turn_server":null}
```

### 客户端配置

客户端配置存储在：
- Windows: `%APPDATA%/easyremote/config.json`
- macOS: `~/Library/Application Support/easyremote/config.json`
- Linux: `~/.config/easyremote/config.json`

```json
{
  "server_url": "ws://localhost:8080",
  "device_name": "My Computer",
  "quality": {
    "frame_rate": 30,
    "resolution_scale": 1.0,
    "image_quality": 80,
    "hardware_acceleration": true
  },
  "auto_start": false,
  "launch_on_boot": false
}
```

## 📖 使用说明

### 远程协助（被控制端）

1. 启动客户端
2. 开启「允许他人远程协助」开关
3. 将设备ID和验证码告知控制方

### 远程控制（控制端）

1. 启动客户端
2. 切换到「远控」标签
3. 输入对方的设备ID和验证码
4. 点击「连接」

### 账号登录

1. 注册/登录账号
2. 设备自动绑定到账号
3. 可在「远控」标签查看已登录的所有设备
4. 在「历史」标签查看控制记录

### 管理后台

1. 创建管理员账号（首次需要手动在数据库中设置 role='admin'）
2. 访问 `http://服务器地址:8080/`
3. 使用管理员账号登录
4. 可管理用户、设备、会话，以及直接远程控制

## 🔧 开发

### 运行测试

```bash
cargo test
```

### 代码检查

```bash
cargo clippy
```

### 格式化代码

```bash
cargo fmt
```

## 📄 API 文档

### 认证接口

| 接口 | 方法 | 说明 |
|------|------|------|
| `/api/auth/register` | POST | 用户注册 |
| `/api/auth/login` | POST | 用户登录 |
| `/api/auth/logout` | POST | 退出登录 |
| `/api/auth/refresh` | POST | 刷新令牌 |

### 用户接口

| 接口 | 方法 | 说明 |
|------|------|------|
| `/api/users/me` | GET | 获取当前用户 |
| `/api/users/me` | POST | 更新用户信息 |

### 设备接口

| 接口 | 方法 | 说明 |
|------|------|------|
| `/api/devices` | GET | 获取设备列表 |
| `/api/devices/register` | POST | 注册设备 |
| `/api/devices/:id` | GET | 获取设备详情 |
| `/api/devices/:id` | DELETE | 移除设备 |
| `/api/devices/:id/offline` | POST | 强制下线 |

### ICE 配置接口

| 接口 | 方法 | 说明 |
|------|------|------|
| `/api/ice-servers` | GET | 获取 ICE 服务器配置（STUN/TURN）|

### 会话接口

| 接口 | 方法 | 说明 |
|------|------|------|
| `/api/sessions` | GET | 获取活跃会话 |
| `/api/sessions/history` | GET | 获取历史记录 |
| `/api/sessions/:id` | GET | 获取会话详情 |
| `/api/sessions/:id/end` | POST | 结束会话 |

### WebSocket 接口

| 接口 | 说明 |
|------|------|
| `/ws/signal?device_id=xxx` | 信令WebSocket |
| `/ws/remote/:device_id` | 浏览器远程控制WebSocket |

## 🛣️ 路线图

- [x] 基础架构
- [x] 用户认证
- [x] 设备管理
- [x] 信令服务
- [x] 客户端GUI
- [x] 管理后台
- [x] 内置 STUN 服务器
- [ ] P2P连接优化
- [ ] TURN 中转服务
- [ ] 文件传输
- [ ] 音频传输
- [ ] 多显示器选择
- [ ] 移动端适配

## 📜 许可证

MIT License

## 🤝 贡献

欢迎提交 Issue 和 Pull Request！
