guoyu/_已清理文件备份_周六 22512/md/屏幕流监控功能实现方案.md
2025-12-06 20:11:36 +08:00

9.6 KiB
Raw Blame History

屏幕流监控功能实现方案

一、功能概述

基于 UniApp 开发的安卓 App实现局域网内后台按需调取学习端屏幕画面的功能。

核心需求

  1. 按需启动:后台管理端点击特定学生账号后,触发该账号绑定的安卓 App 启动屏幕捕获
  2. 实时传输:将学习画面实时传输到后台
  3. 资源节省:不点击时 App 不进行任何捕获和传输操作
  4. 局域网传输:全程在局域网内传输,不依赖外网
  5. 权限兼容:适配安卓 10+ 版本,处理好屏幕捕获权限、后台保活

二、技术方案

2.1 架构设计

┌─────────────────┐         WebSocket          ┌─────────────────┐
│   学生端 App    │ ◄─────────────────────────► │   后台管理端    │
│  (UniApp)       │                              │   (RuoYi)      │
│                 │                              │                 │
│  - 屏幕捕获     │                              │  - 指令控制     │
│  - WebSocket    │                              │  - 画面显示     │
│  - 按需启动     │                              │  - 学生管理     │
└─────────────────┘                              └─────────────────┘

2.2 技术选型

前端UniApp

  • 屏幕捕获:使用 plus.screen.capture API安卓原生
  • 通信协议WebSocket实时双向通信
  • 图片编码Base64便于 WebSocket 传输)
  • 后台保活:使用 FOREGROUND_SERVICE 权限

后端RuoYi

  • WebSocket 服务器Spring WebSocket
  • 控制接口RESTful API
  • 画面转发WebSocket 消息转发

2.3 数据流程

  1. 启动监控流程

    后台点击学生 → 调用控制接口 → 发送 WebSocket 指令 → 学生端接收指令 → 开始屏幕捕获 → 传输画面
    
  2. 停止监控流程

    后台点击停止 → 调用控制接口 → 发送 WebSocket 指令 → 学生端接收指令 → 停止屏幕捕获
    
  3. 画面传输流程

    学生端捕获屏幕 → Base64 编码 → WebSocket 发送 → 后台接收 → 解码显示
    

三、实现细节

3.1 学生端实现UniApp

3.1.1 屏幕流捕获工具类 (screenStream.js)

核心功能:

  • WebSocket 连接管理
  • 接收后台指令(启动/停止)
  • 屏幕捕获和传输
  • 自动重连机制
  • 后台保活

关键代码:

// 连接 WebSocket
connect() {
    const wsUrl = this.getWebSocketUrl()
    this.ws = uni.connectSocket({
        url: wsUrl,
        header: {
            'Authorization': `Bearer ${uni.getStorageSync('token') || ''}`
        }
    })
}

// 开始捕获
startCapture(interval = 500) {
    this.isCapturing = true
    this.captureTimer = setInterval(() => {
        this.captureAndSend()
    }, interval)
}

// 捕获并发送
async captureAndSend() {
    const screenshotData = await this.captureScreen()
    this.sendMessage({
        type: 'screen_frame',
        userId: this.userId,
        data: screenshotData,
        timestamp: Date.now()
    })
}

3.1.2 权限配置

manifest.json 中添加必要权限:

{
  "android": {
    "permissions": [
      "<uses-permission android:name=\"android.permission.FOREGROUND_SERVICE\"/>",
      "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>"
    ]
  }
}

3.1.3 应用初始化

App.vue 中初始化屏幕流服务:

onShow() {
    const token = uni.getStorageSync('token')
    if (token) {
        this.initScreenStream()
    }
}

3.2 后端实现RuoYi

3.2.1 WebSocket 处理器 (ScreenStreamWebSocketHandler.java)

核心功能:

  • 管理学生端连接
  • 管理监控端连接
  • 转发屏幕帧数据
  • 发送控制指令

关键代码:

@ServerEndpoint("/ws/screenStream/{userId}")
@Component
public class ScreenStreamWebSocketHandler {
    // 学生端连接映射
    private static ConcurrentHashMap<String, ScreenStreamWebSocketHandler> studentConnections;
    
    // 监控端连接映射
    private static ConcurrentHashMap<String, ScreenStreamWebSocketHandler> monitorConnections;
    
    // 发送指令给学生端
    public static void sendCommandToStudent(String studentUserId, String command, Integer interval) {
        ScreenStreamWebSocketHandler handler = studentConnections.get(studentUserId);
        if (handler != null) {
            handler.sendMessage(JSON.toJSONString(cmd));
        }
    }
}

3.2.2 控制接口 (ScreenStreamController.java)

接口列表:

  • POST /study/screenStream/start - 启动屏幕流捕获
  • POST /study/screenStream/stop - 停止屏幕流捕获
  • POST /study/screenStream/checkOnline - 检查学生是否在线
  • POST /study/screenStream/onlineCount - 获取在线学生数

3.2.3 安全配置

SecurityConfig.java 中添加 WebSocket 路径免认证:

.antMatchers("/ws/**").permitAll()

3.3 后台管理端实现

3.3.1 屏幕流监控页面 (screenStream/index.vue)

功能特性:

  • 学生列表展示(带在线状态)
  • 点击学生开始/停止监控
  • 实时显示屏幕画面
  • WebSocket 接收画面数据

关键代码:

// 连接 WebSocket 接收画面
connectWebSocket(studentId) {
    const wsUrl = `ws://${host}/ws/screenStream/${studentId}`
    this.ws = new WebSocket(wsUrl)
    
    this.ws.onmessage = (event) => {
        const message = JSON.parse(event.data)
        if (message.type === "screen_frame") {
            this.currentScreenFrame = `data:image/jpeg;base64,${message.data}`
        }
    }
}

// 启动监控
async startMonitor() {
    await startScreenStream(this.currentStudent.userId, 500)
    this.currentStudent.isMonitoring = true
    this.connectWebSocket(this.currentStudent.userId)
}

四、部署说明

4.1 前端部署

  1. 配置服务器地址

    • 修改 frontend-uniapp/src/utils/config.js 中的 SERVER_HOST
    • 确保 WebSocket 地址正确
  2. 编译打包

    cd frontend-uniapp
    npm run build:app
    
  3. 权限说明

    • 安卓 10+ 需要用户手动授予屏幕捕获权限
    • 首次启动时会请求相关权限

4.2 后端部署

  1. 确保 WebSocket 支持

    • 检查 pom.xml 中已包含 spring-boot-starter-websocket 依赖
  2. 配置安全策略

    • WebSocket 路径 /ws/** 已配置为免认证
    • 实际认证在 WebSocket 处理器中处理
  3. 启动服务

    cd RuoYi-Vue-redis
    mvn clean install
    java -jar ry-news-admin/target/ry-news-admin.jar
    

五、性能优化

5.1 传输优化

  1. 图片质量调整

    • 默认质量 0.7(可调整)
    • 根据网络情况动态调整
  2. 捕获频率

    • 默认 500ms约 2 帧/秒)
    • 可根据需求调整
  3. 数据压缩

    • 使用 JPEG 格式(比 PNG 小)
    • Base64 编码传输

5.2 资源管理

  1. 按需启动

    • 只有后台点击时才启动捕获
    • 不监控时完全停止,节省资源
  2. 连接管理

    • 自动重连机制
    • 连接断开时停止捕获
  3. 后台保活

    • 使用前台服务权限
    • 确保应用在后台时也能运行

六、注意事项

6.1 权限问题

  1. 屏幕捕获权限

    • 安卓 10+ 需要 MediaProjection 权限
    • 需要用户手动授权
  2. 后台运行权限

    • 需要 FOREGROUND_SERVICE 权限
    • manifest.json 中已配置

6.2 兼容性

  1. 安卓版本

    • 最低支持Android 5.0 (API 21)
    • 推荐Android 10+ (API 29+)
  2. 网络要求

    • 必须在同一局域网内
    • 确保防火墙允许 WebSocket 连接

6.3 安全性

  1. 认证机制

    • WebSocket 连接时携带 Token
    • 后端验证用户身份
  2. 数据加密

    • 建议在生产环境使用 WSSWebSocket Secure
    • 局域网环境可考虑使用 HTTP

七、测试建议

7.1 功能测试

  1. 连接测试

    • 测试学生端 WebSocket 连接
    • 测试后台管理端连接
  2. 指令测试

    • 测试启动/停止指令
    • 测试指令响应时间
  3. 画面传输测试

    • 测试画面清晰度
    • 测试传输延迟
    • 测试多学生同时监控

7.2 性能测试

  1. 资源占用

    • 监控 CPU 和内存占用
    • 监控网络带宽占用
  2. 稳定性测试

    • 长时间运行测试
    • 网络中断恢复测试

八、后续优化方向

  1. WebRTC 方案

    • 如果 WebSocket 方案性能不足,可考虑 WebRTC
    • 需要开发原生插件支持
  2. 流媒体服务器

    • 使用 RTMP/RTSP 协议
    • 需要部署流媒体服务器(如 SRS
  3. 画面录制

    • 支持录制监控画面
    • 保存为视频文件
  4. 多画面监控

    • 支持同时监控多个学生
    • 画面分屏显示

九、常见问题

Q1: 屏幕捕获失败?

A: 检查是否授予屏幕捕获权限,安卓 10+ 需要用户手动授权。

Q2: WebSocket 连接失败?

A: 检查网络连接、防火墙设置,确保在同一局域网内。

Q3: 画面延迟高?

A: 可以调整捕获间隔(默认 500ms或降低图片质量。

Q4: 应用后台时停止捕获?

A: 检查是否授予后台运行权限,确保 FOREGROUND_SERVICE 权限已配置。

Q5: 多学生同时监控性能问题?

A: 可以限制同时监控的学生数量,或使用流媒体服务器方案。