# 远程屏幕监控系统 一个基于 Node.js 的实时远程屏幕监控和控制系统,支持鼠标和键盘的远程操作、剪贴板同步、文件传输等功能。 ## 功能特点 - 🎥 **实时屏幕流** - 低延迟的屏幕视频流传输,使用 FFmpeg 进行 MPEG1 编码 - 🖱️ **鼠标控制** - 远程鼠标移动、点击和滚轮操作 - ⌨️ **键盘控制** - 远程键盘输入,支持特殊键和组合键 - 📋 **剪贴板同步** - 支持文本和图片的双向剪贴板同步 - **文件传输** - 支持大文件分块上传、下载和文件管理 - 🔒 **安全认证** - bcrypt 密码哈希 + JWT Token 认证 - 🌐 **内网穿透** - 集成 FRP 客户端,支持外网访问 - 📦 **Git 服务** - 可选集成 Gitea,提供代码托管服务 - 📝 **日志系统** - 完整的运行日志记录 - ⚙️ **灵活配置** - 支持配置文件和环境变量配置 ## 快速开始 ### 环境要求 - Node.js >= 16.0.0 - Windows 操作系统(输入控制功能需要) - FFmpeg(已内置安装) ### 安装依赖 ```bash npm install ``` ### 启动服务 ```bash npm run dev # 或 npm start ``` 访问 http://localhost:3000 查看屏幕流。 ## 配置 配置文件位于 `config/default.json`,可配置项包括: ```json { "server": { "port": 3000, "host": "0.0.0.0" }, "stream": { "fps": 30, "bitrate": "4000k", "gop": 10, "preset": "ultrafast", "resolution": { "width": 1920, "height": 1080 } }, "input": { "mouseEnabled": true, "keyboardEnabled": true, "sensitivity": 1.0 }, "security": { "password": "", "tokenExpiry": 3600 }, "frp": { "enabled": true, "frpcPath": "./frp/frpc.exe", "configPath": "./frp/frpc.toml" }, "gitea": { "enabled": true } } ``` ### 配置说明 | 配置项 | 说明 | 默认值 | |--------|------|--------| | server.port | 服务器端口 | 3000 | | server.host | 服务器监听地址 | 0.0.0.0 | | stream.fps | 视频帧率 | 30 | | stream.bitrate | 视频码率 | 4000k | | stream.gop | GOP 大小(关键帧间隔) | 10 | | stream.preset | 编码预设 | ultrafast | | stream.resolution | 视频分辨率 | 1920x1080 | | input.mouseEnabled | 是否启用鼠标控制 | true | | input.keyboardEnabled | 是否启用键盘控制 | true | | input.sensitivity | 鼠标灵敏度 | 1.0 | | security.password | 访问密码(空表示不需要密码) | "" | | security.tokenExpiry | Token 有效期(秒) | 3600 | | frp.enabled | 是否启用 FRP 内网穿透 | true | | gitea.enabled | 是否启用 Gitea 服务 | true | ### 环境变量配置 所有配置项都可以通过环境变量覆盖,格式为 `REMOTE_
_`: ```bash # 设置服务器端口 REMOTE_SERVER_PORT=8080 # 设置密码 REMOTE_SECURITY_PASSWORD=your_password # 设置 JWT 密钥 JWT_SECRET=your_jwt_secret ``` ## API 接口 ### 认证接口 #### 登录 ```bash POST /login Content-Type: application/json { "password": "your_password" } ``` 响应:设置 `auth` Cookie 并重定向到首页。 #### API 登录 ```bash POST /api/auth/login Content-Type: application/json { "password": "your_password" } ``` 响应: ```json { "success": true, "token": "jwt_token_here" } ``` #### 验证 Token ```bash POST /api/auth/verify Authorization: Bearer ``` 响应: ```json { "success": true, "valid": true, "userId": "default-user" } ``` ### 鼠标控制 ```bash POST /api/input/mouse/move Content-Type: application/json { "x": 100, "y": 200 } ``` ```bash POST /api/input/mouse/down Content-Type: application/json { "button": "left" # "left", "right" 或 "middle" } ``` ```bash POST /api/input/mouse/up Content-Type: application/json { "button": "left" } ``` ```bash POST /api/input/mouse/click Content-Type: application/json { "button": "left" } ``` ```bash POST /api/input/mouse/wheel Content-Type: application/json { "delta": 120 # 正值向上滚动,负值向下滚动 } ``` ### 键盘控制 ```bash POST /api/input/keyboard/down Content-Type: application/json { "key": "enter" } ``` ```bash POST /api/input/keyboard/up Content-Type: application/json { "key": "enter" } ``` ```bash POST /api/input/keyboard/press Content-Type: application/json { "key": "enter" } ``` ```bash POST /api/input/keyboard/type Content-Type: application/json { "text": "Hello World" } ``` 支持的特殊键:`enter`, `backspace`, `tab`, `escape`, `delete`, `home`, `end`, `pageup`, `pagedown`, `up`, `down`, `left`, `right`, `f1`-`f12`, `ctrl`, `alt`, `shift`, `win`, `space` ### 流媒体接口 ```bash GET /api/stream/info ``` 响应: ```json { "success": true, "stream": { "status": "running", "resolution": { "width": 1920, "height": 1080 }, "fps": 30, "bitrate": "4000k", "gop": 10, "encoder": "mpeg1video" } } ``` ```bash POST /api/stream/start ``` ```bash POST /api/stream/stop ``` ### 文件传输接口 ```bash GET /api/files ``` 响应: ```json { "files": [ { "name": "example.txt", "size": 1024, "modified": "2026-03-05T10:00:00.000Z", "type": ".txt" } ] } ``` ```bash GET /api/files/browse?path=relative/path ``` 响应: ```json { "items": [ { "name": "folder", "isDirectory": true, "size": 0, "modified": "2026-03-05T10:00:00.000Z", "type": "directory" } ], "currentPath": "relative/path", "parentPath": "" } ``` ```bash POST /api/files/upload/start Content-Type: application/json { "filename": "large_file.zip", "totalChunks": 10, "fileSize": 50000000 } ``` 响应: ```json { "fileId": "abc123", "chunkSize": 5242880, "message": "Upload session started" } ``` ```bash POST /api/files/upload/chunk Content-Type: multipart/form-data fileId: abc123 chunkIndex: 0 chunk: ``` ```bash POST /api/files/upload/merge Content-Type: application/json { "fileId": "abc123", "totalChunks": 10, "filename": "large_file.zip" } ``` ```bash GET /api/files/:filename ``` 支持 Range 请求头进行断点续传。 ```bash DELETE /api/files/:filename ``` ### WebSocket 消息类型 连接地址:`ws://localhost:3000/ws` #### 客户端发送 | 类型 | 说明 | 数据 | |------|------|------| | mouseMove | 鼠标移动 | `{ type: "mouseMove", x: 100, y: 200 }` | | mouseDown | 鼠标按下 | `{ type: "mouseDown", button: "left" }` | | mouseUp | 鼠标释放 | `{ type: "mouseUp", button: "left" }` | | mouseWheel | 鼠标滚轮 | `{ type: "mouseWheel", delta: 120 }` | | keyDown | 键盘按下 | `{ type: "keyDown", key: "enter" }` | | keyUp | 键盘释放 | `{ type: "keyUp", key: "enter" }` | | clipboardGet | 获取剪贴板 | `{ type: "clipboardGet" }` | | clipboardSet | 设置剪贴板 | `{ type: "clipboardSet", contentType: "text", data: "content" }` | #### 服务端发送 | 类型 | 说明 | 数据 | |------|------|------| | screenInfo | 屏幕信息 | `{ type: "screenInfo", width: 1920, height: 1080 }` | | clipboardData | 剪贴板数据 | `{ type: "clipboardData", contentType: "text", data: "content", size: 100 }` | | clipboardResult | 剪贴板操作结果 | `{ type: "clipboardResult", success: true }` | | clipboardTooLarge | 剪贴板内容过大 | `{ type: "clipboardTooLarge", size: 1000000 }` | ## 项目结构 ``` remote/ ├── src/ │ ├── config/ # 配置管理 │ │ ├── index.js # 配置加载器 │ │ └── schema.js # 配置验证模式 │ ├── controllers/ # 控制器层 │ │ ├── AuthController.js # 认证控制器 │ │ ├── InputController.js# 输入控制器 │ │ └── StreamController.js# 流媒体控制器 │ ├── core/ # 核心模块 │ │ ├── App.js # 应用主类 │ │ ├── Container.js # 依赖注入容器 │ │ ├── EventBus.js # 事件总线 │ │ ├── ErrorHandler.js # 错误处理器 │ │ └── events.js # 事件类型定义 │ ├── middlewares/ # 中间件 │ │ ├── auth.js # 认证中间件 │ │ ├── error.js # 错误处理中间件 │ │ └── rateLimit.js # 限流中间件 │ ├── routes/ # 路由层 │ │ ├── index.js # 路由汇总 │ │ ├── auth.js # 认证路由 │ │ ├── files.js # 文件路由 │ │ ├── input.js # 输入路由 │ │ └── stream.js # 流媒体路由 │ ├── server/ # 服务器层 │ │ ├── Server.js # HTTP 服务器 │ │ ├── WebSocketServer.js# WebSocket 服务器 │ │ ├── StreamBroadcaster.js# 流广播器 │ │ ├── InputHandler.js # 输入处理器 │ │ └── messageTypes.js # 消息类型定义 │ ├── services/ # 服务层 │ │ ├── auth/ # 认证服务 │ │ │ ├── AuthService.js │ │ │ └── TokenManager.js │ │ ├── clipboard/ # 剪贴板服务 │ │ │ └── ClipboardService.js │ │ ├── file/ # 文件服务 │ │ │ └── FileService.js │ │ ├── input/ # 输入服务 │ │ │ ├── InputService.js │ │ │ └── PowerShellInput.js │ │ ├── network/ # 网络服务 │ │ │ ├── FRPService.js │ │ │ └── GiteaService.js │ │ ├── stream/ # 流媒体服务 │ │ │ ├── FFmpegEncoder.js │ │ │ ├── ScreenCapture.js │ │ │ └── StreamService.js │ │ └── index.js # 服务汇总 │ ├── utils/ # 工具类 │ │ ├── config.js # 配置工具 │ │ ├── logger.js # 日志工具 │ │ └── paths.js # 路径工具 │ └── index.js # 应用入口 ├── config/ │ └── default.json # 默认配置 ├── docs/ # 文档目录 │ ├── 开发/ # 开发文档 │ └── 指南/ # 使用指南 ├── frp/ # FRP 内网穿透 │ ├── frpc.exe │ ├── frpc.toml │ └── frpc-runtime.toml ├── gitea/ # Gitea Git 服务 ├── logs/ # 日志目录 │ ├── combined.log # 所有日志 │ └── error.log # 错误日志 ├── public/ # 前端静态文件 │ ├── css/ │ │ └── main.css │ ├── js/ │ │ ├── app.js # 应用入口 │ │ ├── file-panel.js # 文件传输面板 │ │ ├── input.js # 输入处理 │ │ ├── jsmpeg.min.js # JSMpeg 播放器 │ │ ├── player.js # 视频播放器 │ │ └── utils.js # 工具函数 │ └── index.html ├── scripts/ │ └── migrate-password.js # 密码迁移脚本 ├── uploads/ # 上传文件目录 ├── .gitignore ├── package.json └── README.md ``` ## 构建与部署 ### 开发环境 ```bash npm run dev ``` ### 生产环境打包 使用 pkg 打包为可执行文件: ```bash npm run build ``` 打包后的文件位于 `dist/` 目录: - `remote-screen-monitor.exe` - 主程序 - `public/` - 前端静态文件 - `config/` - 配置文件 - `frp/` - FRP 客户端 - `ffmpeg.exe` - FFmpeg 编码器 ### Windows 服务安装 使用 NSSM 将应用安装为 Windows 服务: ```powershell # 安装服务 nssm install RemoteApp "C:\path\to\remote-screen-monitor.exe" # 设置工作目录 nssm set RemoteApp AppDirectory "C:\path\to\app" # 设置启动类型 nssm set RemoteApp Start SERVICE_AUTO_START # 启动服务 nssm start RemoteApp ``` 详细说明请参考 [NSSM使用指南](docs/指南/NSSM使用指南.md)。 ## 安全注意事项 ⚠️ **重要提示**: - 在公共网络上使用时,务必设置密码保护 - 建议使用 HTTPS/WSS(通过反向代理如 Nginx) - 不要使用 root/Administrator 权限运行此服务 - 定期更换密码和 JWT 密钥 ### 密码安全 系统支持 bcrypt 密码哈希。使用迁移脚本生成安全的密码哈希: ```bash node scripts/migrate-password.js ``` 将生成的哈希值设置到环境变量 `REMOTE_SECURITY_PASSWORD` 中。 ## 故障排除 ### 鼠标/键盘控制不工作 确保以管理员权限运行(Windows),某些操作可能需要提升的权限。 ### 视频流卡顿 - 降低 FPS 或分辨率 - 降低视频码率 - 检查网络带宽 ### 日志查看 日志文件位于 `logs/` 目录: - `logs/combined.log` - 所有日志 - `logs/error.log` - 错误日志 ## 技术栈 - **后端**: Node.js, Express 5.x, ws (WebSocket), winston (日志) - **前端**: HTML5 Canvas, JSMpeg 播放器 - **视频编码**: FFmpeg (mpeg1video) - **输入模拟**: PowerShell + Windows API (user32.dll) - **认证**: bcrypt, jsonwebtoken - **文件处理**: multer, fs-extra - **内网穿透**: FRP (Fast Reverse Proxy) - **打包**: pkg ## 许可证 ISC