# WebRTC 网页远程控制 (WebRTCControllerWeb)

基于 **Vue3 + Vite** 的 WebRTC 网页远程控制端，参考并兼容以下既有项目：

- `WebRTCSignalServer` —— Java/Spring 信令服务器（WebSocket，端点 `/ws/signal`）
- `WebRTCControlled` —— Android 被控端（采集屏幕、接收控制指令）
- `WebRTCController` / `webrtc_controller_flutter` —— Android / Flutter 控制端

本项目的定位是 **网页版控制端 (CONTROLLER)**，与原有信令协议、protobuf 控制协议 **完全兼容**：

- 通过 WebSocket 连接信令服务器并注册为 `CONTROLLER`
- 作为 OFFER 方创建 WebRTC 连接（仅接收远端视频 `recvonly` + 一条控制用 `DataChannel`）
- 在浏览器中显示被控端画面，并通过触摸/鼠标/导航按键采集输入
- 将输入转换为相对坐标 (0.0~1.0) 的 protobuf `ControlMessage`，经 DataChannel 发送给被控端执行

## 目录结构

```
WebRTCControllerWeb/
├── index.html
├── package.json
├── vite.config.js
├── public/
│   └── control_message.proto        # 与 Android/Flutter 完全一致的 protobuf 定义
├── server/                          # 可选：轻量 Node 信令服务器（与 Spring 版协议一致）
│   ├── index.js
│   └── package.json
└── src/
    ├── main.js
    ├── App.vue
    ├── style.css
    ├── proto/controlMessage.js      # protobufjs 运行时编码
    ├── services/
    │   ├── SignalingClient.js       # WebSocket 信令（对应 Android WebSocketClient）
    │   └── WebRtcController.js       # WebRTC + DataChannel（对应 WebRtcClient）
    ├── store/controllerStore.js     # 全局状态与流程编排（对应 RemoteController）
    └── components/
        ├── ConnectionPanel.vue      # 信令连接 / 设备列表 / 发起控制
        ├── RemoteScreen.vue         # 远端视频 + 触摸/滑动采集层
        ├── ControlBar.vue           # 主页/返回/多任务/音量/电源等导航键
        └── StatsBar.vue             # 连接统计（分辨率/帧率/下载速率等）
```

## 运行

### 1. 准备信令服务器（二选一）

**方式 A：复用现有 Spring 信令服务器**
直接启动 `WebRTCSignalServer` 即可（默认 `ws://<host>:8088/ws/signal`）。

**方式 B：使用本项目自带的 Node 信令服务器**
```bash
cd server
npm install
npm start          # 监听 ws://localhost:8088/ws/signal
```

### 2. 启动被控端
在安卓设备安装并运行 `WebRTCControlled`，保持其在线并连接到同一信令服务器。

### 3. 启动网页控制端
```bash
cd WebRTCControllerWeb
npm install
npm run dev        # 默认 http://localhost:5173
```

> 浏览器需支持 WebRTC。本地 `http://localhost` 可直接使用；
> 部署到远程地址时建议使用 `https://` 与 `wss://`，否则部分浏览器会拦截。

### 4. 使用
1. 左侧填写信令服务器地址与「本机设备 ID」（已自动生成随机 ID）。
2. 点击「连接信令服务器」，再点击「刷新设备列表」获取在线被控端。
3. 选择目标设备，点击「发起远程控制」。
4. 被控端弹出连接请求并「接受」后，右侧出现屏幕画面。
5. 在画面上 **触摸/滑动** 即可操控；底部按钮对应系统导航键（主页/返回/多任务/菜单/音量/电源）。

## 控制协议要点

- **信令消息**（`SignalMessage`）：`type / fromDeviceId / toDeviceId / deviceType / payload(JSON 字符串)`，
  类型含 `REGISTER / OFFER / ANSWER / ICE_CANDIDATE / DEVICE_LIST` 等。
- **DataChannel** 标签固定为 `control_channel`，创建参数 `ordered:false, maxRetransmits:0`（非可靠、无序，最低延迟）。
- **控制指令**（`ControlMessage`，protobuf 二进制）：
  - `TOUCH=1` 单击（x,y）
  - `SWIPE=2` 滑动（x1,y1,x2,y2,duration）
  - `KEY=3` 按键（key_code；被控端自动完成 按下+抬起）
  - `LONG_PRESS=4` 长按（x,y）
  - `MOTION_EVENT=5` 原始指针动作（motion_action: 0=DOWN/1=UP/2=MOVE；x,y）

坐标均为相对屏幕百分比 (0.0~1.0)，因此不同分辨率设备间可直接换算。

## 与原有项目的对应关系

| 能力 | Android/Flutter | 本项目 (Vue3) |
| --- | --- | --- |
| 信令注册 | `WebSocketClient.registerDevice()` | `SignalingClient.register()` |
| 创建连接 | `WebRtcClient.createOffer()` | `WebRtcController.createOffer()` |
| 触摸采集 | `RemoteTouchView` | `RemoteScreen.vue`（pointer 事件 + 相对坐标映射） |
| 指令构造 | `ControlCommands` | `WebRtcController.sendTouch/...` + `controlMessage.js` |
| 流程编排 | `MainActivity` / `RemoteController` | `controllerStore.js` |

## 备注

- ICE/TURN 配置见 `src/store/controllerStore.js` 的 `DEFAULT_ICE_SERVERS`，请按需替换为你自己的 TURN 凭据。
- 本网页端作为 **控制端**，被控端仍为 Android（`WebRTCControlled`）。
