资讯动态

远程屏幕监控系统:轻量级视觉审计方案设计与实现

发布时间:2026/10/21 5:29:58 来源:尧图企业网站定制
简介本资源是一个基于Java实现的轻量级远程电脑屏幕监控系统源码包面向Java初学者与网络编程学习者解决远程实时查看与控制目标计算机屏幕的技术实践问题适用于远程技术支持、家庭设备监护及课设项目开发等场景。压缩包为12KB的RAR格式共含14个文件包括5个核心Java源文件.java、6个编译生成的字节码类文件.class以及Eclipse项目配置文件.project、.classpath和IDE设置文件.prefs完整呈现了标准Java桌面端网络监控项目的工程结构与模块划分。目前已有596人学习下载。读者可直接导入Eclipse运行调试深入理解TCP通信建连、屏幕图像捕获Windows API调用、JPEG增量编码传输、WebSocket双向实时推送及多线程协同等关键技术实现细节掌握从协议选型、图像压缩到安全控制的全链路开发逻辑。1. 远程电脑屏幕监控不是远程控制而是“只看不碰”的轻量级视觉审计方案你有没有遇到过这种场景某高校实验室需要定期抽查学生上机行为但又不能干扰正常教学某公司IT部门要确认终端是否在执行合规操作却无法部署带外管理硬件甚至某开发者自己在家调试多台开发机想一眼看清每台的桌面状态又不想开一堆远程桌面窗口卡死本地。这时候“远程电脑屏幕监控”就不是“远程控制”的简化版而是一个有明确边界的设计命题——它必须做到只采集画面、不接管输入、不依赖用户交互、低带宽占用、服务端可集中拉取、客户端零配置启动即生效。这套方案专为需要“视觉可见性”而非“操作权”的场景而生适用于课程设计、毕设、中小规模IT运维审计等真实交付场景。它不追求高帧率游戏直播效果但要求画面稳定、延迟可控、断线可续、资源占用透明——换句话说它解决的是“我怎么知道那台电脑此刻在显示什么”而不是“我怎么操作那台电脑”。2. 总体架构设计三层结构与四个核心模块的职责划分整套远程屏幕监控系统采用清晰的三层架构采集端Client→ 传输代理Relay→ 展示服务端Viewer Server。它刻意回避了P2P直连或WebRTC复杂协商也不引入消息队列或微服务治理全部基于TCP长连接轻量HTTP API实现确保学生能在一个周末搭通、从业者能三天内嵌入现有运维体系。2.1 采集端设计无感运行、按需截图、内存可控采集端是部署在被监控电脑上的轻量程序核心逻辑是定时截图 → 压缩编码 → 推送至中继 → 本地缓存最近3帧用于断线重传。关键设计点在于“无感”二字——它不弹窗、不占任务栏、不注册开机自启由外部脚本或服务管理器控制且默认以最小权限运行Windows下用CreateProcessAsUser以当前登录用户身份启动Linux下用DISPLAY:0绕过X11权限限制。以下是采集端主循环的核心Python片段使用msscv2组合兼顾跨平台与性能# client/capture_loop.py import mss import cv2 import numpy as np import time import socket def capture_and_send(sct, sock, quality40): # 截图全屏支持多屏合并 monitor sct.monitors[0] # 全屏合并 img np.array(sct.grab(monitor)) # BGR→RGB→JPEG压缩质量40平衡清晰度与体积 img_rgb cv2.cvtColor(img, cv2.COLOR_BGRA2RGB) _, buffer cv2.imencode(.jpg, img_rgb, [cv2.IMWRITE_JPEG_QUALITY, quality]) # 添加8字节头部uint64_t 表示数据长度网络字节序 length_bytes len(buffer).to_bytes(8, big) try: sock.sendall(length_bytes buffer.tobytes()) return True except (ConnectionResetError, BrokenPipeError): return False # 主循环每秒1帧超时自动降频 with mss.mss() as sct: while True: start time.time() if not capture_and_send(sct, sock): print([WARN] Send failed, reconnecting...) sock reconnect_to_relay() continue # 动态帧率控制若耗时800ms则下一帧延至1.5秒后 elapsed time.time() - start sleep_time max(1.0, 1.5 - elapsed) if elapsed 0.8 else 1.0 time.sleep(sleep_time)提示mss比PIL.ImageGrab快35倍且不触发UACcv2.imencode比PIL.save压缩更可控头部8字节长度字段是后续协议扩展的基础如支持多屏分片、时间戳嵌入不是冗余设计。2.2 传输代理设计单点接入、连接复用、心跳保活传输代理Relay是整个系统的“流量调度中心”但它不做任何画面处理只做三件事接受客户端TCP连接、维护连接池、将原始JPG流原样转发给Viewer Server。它不解析图像内容不转码不存储因此CPU和内存占用极低实测单核100%负载下可支撑300并发连接。其核心是异步I/O模型我们选用asyncio而非gevent因前者标准库支持、调试友好、无隐式协程陷阱。以下是Relay核心转发逻辑relay/server.py# relay/server.py import asyncio import logging class RelayServer: def __init__(self, viewer_host127.0.0.1, viewer_port8081): self.viewer_host viewer_host self.viewer_port viewer_port self.clients {} # {client_id: (reader, writer)} self.viewer_writer None async def handle_client(self, reader, writer): client_id f{writer.get_extra_info(peername)[0]}:{writer.get_extra_info(peername)[1]} self.clients[client_id] (reader, writer) # 尝试连接Viewer Server懒连接首次有数据才建 if not self.viewer_writer: try: _, self.viewer_writer await asyncio.open_connection( self.viewer_host, self.viewer_port ) logging.info(Connected to Viewer Server) except Exception as e: logging.error(fFailed to connect to Viewer: {e}) writer.close() return # 转发循环读客户端→写Viewer while True: try: # 读取8字节长度头 header await reader.readexactly(8) length int.from_bytes(header, big) # 读取图像数据 data await reader.readexactly(length) # 原样转发给Viewer Server self.viewer_writer.write(header data) await self.viewer_writer.drain() except asyncio.IncompleteReadError: logging.info(fClient {client_id} disconnected gracefully) break except Exception as e: logging.warning(fError forwarding from {client_id}: {e}) break # 清理 self.clients.pop(client_id, None) writer.close() async def start(self): server await asyncio.start_server( self.handle_client, 0.0.0.0, 8080 ) async with server: await server.serve_forever()设计说明Relay不保存任何状态所有连接信息仅存于内存字典Viewer Server宕机时Relay缓存客户端连接但暂停转发避免雪崩每个客户端连接独立处理互不影响——这是它能扛住突发连接的关键。2.3 展示服务端设计HTTP接口驱动、多客户端轮询、实时性保障Viewer Server是唯一提供HTTP服务的组件对外暴露两个核心接口GET /api/sessions返回当前在线客户端列表含IP、最后心跳时间、分辨率GET /api/frame/{client_id}返回该客户端最新一帧JPGHTTP 200 JPEG body它不主动拉取画面而是由前端轮询/api/frame/xxx获取最新帧。这种“拉模式”带来三大好处前端可自由控制刷新频率如管理员页面设为2秒/帧大屏监控设为1秒/帧服务端无推送压力天然支持Nginx反向代理缓存Cache-Control: no-cache防止浏览器缓存旧帧。以下是Viewer Server的Flask实现关键部分viewer/app.py# viewer/app.py from flask import Flask, jsonify, send_file, abort import threading import time from io import BytesIO app Flask(__name__) # 内存存储{client_id: {frame: bytes, timestamp: float, resolution: (w,h)}} frame_cache {} cache_lock threading.Lock() app.route(/api/sessions) def list_sessions(): with cache_lock: return jsonify([ { id: cid, ip: cid.split(:)[0], last_seen: int(time.time() - info[timestamp]), resolution: info[resolution] } for cid, info in frame_cache.items() ]) app.route(/api/frame/client_id) def get_frame(client_id): with cache_lock: if client_id not in frame_cache: abort(404, descriptionClient not found or no frame received) info frame_cache[client_id] # 检查帧是否过期5秒未更新则视为离线 if time.time() - info[timestamp] 5: abort(408, descriptionFrame timeout) return send_file( BytesIO(info[frame]), mimetypeimage/jpeg, as_attachmentFalse, download_namef{client_id}.jpg ) # 启动TCP监听线程接收Relay转发的帧数据 def tcp_listener(): import socket sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((0.0.0.0, 8081)) sock.listen(10) while True: conn, addr sock.accept() threading.Thread(targethandle_frame_stream, args(conn, addr), daemonTrue).start() def handle_frame_stream(conn, addr): client_id f{addr[0]}:{addr[1]} while True: try: header conn.recv(8) if len(header) 8: break length int.from_bytes(header, big) data b while len(data) length: chunk conn.recv(min(8192, length - len(data))) if not chunk: break data chunk if len(data) length: with cache_lock: frame_cache[client_id] { frame: data, timestamp: time.time(), resolution: detect_resolution(data) # 简单JPEG解析宽高 } except Exception as e: break conn.close()注意detect_resolution函数通过解析JPEG SOF0标记提取宽高无需完整解码代码约20行此处省略tcp_listener作为后台线程运行与Flask主线程隔离避免阻塞Web请求。3. 关键实现细节跨平台截图、分辨率适配与带宽控制策略这套方案真正落地时最常被问到的三个问题其实是“Windows能截多屏吗”、“Mac上为什么黑屏”、“100台机器同时推带宽会不会炸”。答案不在框架里而在这些具体实现细节中。3.1 多屏合并与动态分辨率识别mss默认支持多屏但需显式指定monitors[0]全屏合并或遍历monitors[1:]单屏。我们选择合并因为监控场景关注“整体桌面状态”而非某块屏内容。但合并后分辨率可能高达7680×2160四K×三屏直接JPEG压缩会吃光内存。因此采集端加入动态缩放策略# client/capture_loop.py 中新增 def get_optimal_scale(resolution): w, h resolution # 根据原始分辨率决定缩放比例目标是短边≈800px short_side min(w, h) if short_side 1600: return 0.25 elif short_side 1200: return 0.33 elif short_side 800: return 0.5 else: return 1.0 # 截图后立即缩放在cv2.imencode前 scale get_optimal_scale((monitor[width], monitor[height])) if scale 1.0: new_w int(monitor[width] * scale) new_h int(monitor[height] * scale) img_rgb cv2.resize(img_rgb, (new_w, new_h))血泪经验不缩放时单帧JPG可达2MB四K屏100台并发就是200MB/s上行缩放后稳定在150KB/帧100台仅15MB/s普通千兆内网毫无压力。这不是画质妥协而是监控场景的合理取舍——你能看清微信窗口标题、浏览器地址栏、IDE当前文件名这就够了。3.2 Mac平台X11兼容与权限绕过macOS Catalina之后屏幕录制需用户授权且mss在Mac上默认走CGDisplayCreateImage易被系统拦截。解决方案是改用pyobjc调用AVFoundation框架以“辅助功能”权限静默捕获。需提前执行# 终端执行一次请求辅助功能权限GUI弹窗 tccutil reset ScreenCapture # 或用脚本自动化需用户点击允许 osascript -e tell app System Events to set isRunning to (name of processes) contains YourApp采集端检测到macOS时自动切换后端# client/capture_loop.py import sys if sys.platform darwin: from AppKit import NSScreen from Quartz import CGWindowListCopyWindowInfo, kCGWindowListOptionOnScreenOnly, kCGNullWindowID # 使用CGWindowListCopyWindowInfo获取窗口列表再用NSScreen.screens()获取主屏 main_screen NSScreen.screens()[0] frame main_screen.frame() # 后续截图逻辑同mss但用CGImageCreateWithImageInRect避坑Mac上不要用pyautogui.screenshot()它依赖pyscreeze在无GUI会话如SSH登录后必然失败mss在Mac需pip install mss --no-binary :all:源码编译否则报错。3.3 带宽自适应与QoS分级机制Relay层不干预数据但Viewer Server可对不同客户端设置QoS等级。例如实验室重点机器/api/frame/192.168.1.101返回原图quality60普通办公机/api/frame/192.168.1.102自动降为quality30移动端查看加参数?q20强制更低质量实现方式是在Viewer Server的get_frame中插入质量重编码逻辑仅当请求带q参数且原始帧非JPEG时才触发避免重复压缩失真# viewer/app.py 中 get_frame 函数内追加 q_param request.args.get(q, typeint) if q_param and 10 q_param 80: # 仅对JPEG做二次压缩防失真 nparr np.frombuffer(info[frame], np.uint8) img cv2.imdecode(nparr, cv2.IMREAD_COLOR) _, compressed cv2.imencode(.jpg, img, [cv2.IMWRITE_JPEG_QUALITY, q_param]) return send_file(BytesIO(compressed.tobytes()), mimetypeimage/jpeg)玄学提示JPEG质量3040是人眼分辨文字/图标的临界点低于30图标边缘发虚高于40带宽陡增但肉眼难辨提升——这个区间是我们压测200台机器后定下的黄金值。4. 部署与配置实战从单机验证到百台集群的五步法这套方案的价值最终体现在能不能“三分钟跑起来三天铺满实验室”。以下是某高校信息中心实际落地的五步法每一步都对应一个可验证的交付物。4.1 第一步单机闭环验证10分钟目标在一台Windows电脑上完成“采集→Relay→Viewer→浏览器查看”全链路。操作清单下载client_win.zip解压后双击start_capture.bat自动以当前用户启动无UAC弹窗启动Relaypython relay/server.py监听0.0.0.0:8080启动Viewerpython viewer/app.py监听0.0.0.0:5000浏览器访问http://localhost:5000/api/sessions确认返回[{id:127.0.0.1:xxxx,ip:127.0.0.1,...}]访问http://localhost:5000/api/frame/127.0.0.1:xxxx看到本地桌面截图验证要点若/api/sessions为空检查采集端日志是否报“connection refused”——说明Relay没起来若/api/frame/xxx返回404检查Relay日志是否显示“Connected to Viewer Server”——说明Relay连不上Viewer。4.2 第二步跨主机采集20分钟目标让另一台电脑如室友的Mac成为被监控端。操作清单在Mac上执行pip3 install mss pyobjc opencv-python修改client/config.json{ relay_host: 192.168.1.100, // Windows主机IP relay_port: 8080, capture_interval: 1.0, jpeg_quality: 40 }运行python client/capture_loop.py回到Windows的http://localhost:5000/api/sessions确认出现Mac的IP注意Mac需提前在“系统设置→隐私与安全性→屏幕录制”中勾选终端或Python进程否则截图全黑。4.3 第三步Relay高可用配置15分钟目标Relay单点故障时采集端自动重连备用Relay。实现方式采集端内置双Relay地址列表主Relay失败后3秒内切备# client/capture_loop.py RELAY_LIST [ (192.168.1.100, 8080), # 主 (192.168.1.101, 8080), # 备 ] def reconnect_to_relay(): for host, port in RELAY_LIST: try: sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(3) sock.connect((host, port)) print(f[INFO] Connected to relay {host}:{port}) return sock except Exception as e: print(f[WARN] Failed to connect to {host}:{port}: {e}) continue raise ConnectionError(All relays unavailable)部署技巧两台Relay用Keepalived做VIP漂移或直接用DNS轮询relays.internal解析为两个A记录采集端无需改代码。4.4 第四步Viewer Server反向代理与HTTPS25分钟目标让校外导师通过https://monitor.school.edu访问且支持Basic Auth。Nginx配置示例/etc/nginx/sites-available/monitorupstream viewer_backend { server 127.0.0.1:5000; } server { listen 443 ssl; server_name monitor.school.edu; ssl_certificate /etc/letsencrypt/live/monitor.school.edu/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/monitor.school.edu/privkey.pem; auth_basic Restricted Access; auth_basic_user_file /etc/nginx/.htpasswd; location /api/ { proxy_pass http://viewer_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 关键禁用缓存确保实时帧 add_header Cache-Control no-cache, no-store, must-revalidate; add_header Pragma no-cache; add_header Expires 0; } location / { alias /var/www/monitor-frontend/; try_files $uri $uri/ /index.html; } }提示前端静态页Vue构建放在/var/www/monitor-frontend/它通过fetch(/api/sessions)获取列表再对每个client_id轮询/api/frame/xxx完全走HTTPS无跨域问题。4.5 第五步百台批量部署Shell脚本一键完成目标30分钟内将采集端部署到100台Windows实验室电脑。使用PDQ Deploy免费版或Ansible但最稳的是Windows批处理PowerShell混合# deploy_all.ps1 以管理员身份运行 $computers Get-Content lab_pc_list.txt # 每行一个IP或主机名 $source_path \\fileserver\deploy\client_win.zip $dest_path C$\temp\screen_monitor foreach ($pc in $computers) { # 复制文件 Copy-Item $source_path \\$pc\$dest_path\ -Recurse # 解压需7z.exe在PATH中 Invoke-Command -ComputerName $pc -ScriptBlock { Expand-Archive $using:dest_path\client_win.zip $using:dest_path\client } # 创建服务使用nssm比sc更稳 Invoke-Command -ComputerName $pc -ScriptBlock { C:\temp\screen_monitor\client\nssm.exe install ScreenMonitorClient $using:dest_path\client\start_capture.bat C:\temp\screen_monitor\client\nssm.exe set ScreenMonitorClient Start SERVICE_AUTO_START C:\temp\screen_monitor\client\nssm.exe set ScreenMonitorClient ObjectName LocalSystem Start-Service ScreenMonitorClient } }踩坑总结nssm比Windows原生sc create更可靠尤其处理批处理启动所有路径用绝对路径避免PowerShell会话工作目录影响实验室电脑若禁用PS远程改用psexec list.txt -u admin -p pwd powershell -c ...。5. 常见问题排查五类高频翻车现场与根因定位这套方案在某高校部署初期80%的工单集中在以下五类问题。它们看似琐碎但每一条都对应一个设计盲区。我把它们整理成“现象→原因→解决”三段式方便你快速定位。5.1 现象采集端日志显示“Connection refused”但Relay进程正在运行原因Relay监听的是0.0.0.0:8080但防火墙阻止了入站连接或Relay启动时绑定127.0.0.1而非0.0.0.0常见于开发环境误配置。解决Linuxsudo ufw status查看防火墙sudo ufw allow 8080开放端口Windowsnetsh advfirewall firewall add rule nameRelay Port dirin actionallow protocolTCP localport8080检查Relay启动命令是否含--host 0.0.0.0asyncio.start_server默认是None等价于0.0.0.0但某些封装脚本会覆盖。5.2 现象Viewer Server的/api/sessions有客户端但/api/frame/xxx始终404原因Relay成功连接Viewer Server但Viewer的TCP监听线程tcp_listener未启动或启动后崩溃如端口8081被占用。解决登录Viewer Server服务器执行lsof -i :8081Linux或netstat -ano | findstr :8081Windows确认8081端口有python进程监听若无检查viewer/app.py中threading.Thread(targettcp_listener, daemonTrue).start()是否被注释或缩进错误查看Viewer日志搜索TCP listener started若无此日志说明线程未启动。5.3 现象Mac客户端截图全黑但Windows客户端正常原因macOS系统未授予终端或Python“屏幕录制”权限或采集端未正确切换到AVFoundation后端。解决打开“系统设置→隐私与安全性→屏幕录制”找到你的终端应用如“iTerm2”或“Terminal”并勾选若用VS Code集成终端需单独勾选“Code Helper (Renderer)”检查采集端代码是否执行了sys.platform darwin分支可在日志中加print(Using AVFoundation on macOS)验证。5.4 现象多台客户端同时上线后Viewer Server响应变慢/api/sessions返回超时原因Viewer Server的tcp_listener是单线程阻塞式socket当大量客户端并发推送帧时主线程被conn.recv()卡住导致Flask HTTP请求无法及时响应。解决将tcp_listener改为asyncio协程与Relay同模型或改用selectors模块实现多路复用更简单方案增加tcp_listener线程数如启动5个线程每个监听不同端口80818085Relay随机选一个转发生产环境强烈建议用Gunicorn部署Flask并设置--workers 4 --threads 2。5.5 现象浏览器轮询/api/frame/xxx时画面卡在某一帧不再更新原因浏览器缓存了HTTP响应尽管设置了Cache-Control: no-cache但某些企业代理或老旧浏览器仍会缓存或Viewer Server的frame_cache字典被并发写入破坏threading.Lock未覆盖所有写入点。解决前端轮询URL强制加时间戳参数/api/frame/xxx?t${Date.now()}检查viewer/app.py中所有修改frame_cache的地方包括handle_frame_stream和任何未来扩展的API确保with cache_lock:包裹在handle_frame_stream开头加print(fReceived frame for {client_id}, size {len(data)})确认数据确实在流入。6. 验收与答辩用三张表、一个演示脚本、两次压力测试搞定交付毕设或课设答辩老师最关心三件事你真的做出来了它真的能用它比别人强在哪我带过的十几个项目凡是顺利通过的都准备了这三张表、一个脚本、两次测试。不是炫技是把“可信度”量化出来。6.1 验收参数表定义什么是“可用”很多同学答辩时被问“延迟多少支持多少台”支吾半天。其实只要提前定义好验收阈值并实测填表就能镇住全场。我们用这张表回答所有性能质疑指标阈值实测值100台测试方法单帧端到端延迟采集→浏览器显示≤ 1.5s1.2s ± 0.3sChrome DevTools Network Tab 记录/api/frame/xxx请求时间100台并发时Relay内存占用≤ 1.2GB980MBps aux --sort-%mem | head -20Viewer Server QPS/api/sessions≥ 500620ab -n 10000 -c 100 http://localhost:5000/api/sessions单客户端断线重连时间≤ 5s3.1skill -9采集端进程观察/api/sessions中last_seen恢复时间最小可识别文字大小截图中≥ 12px14pxChrome地址栏在42寸屏上用卷尺测量文字像素高度提示表格数据必须真实可复现。我一般会在答辩前一晚在实验室真实机器上跑一遍截图保存ab和ps输出答辩时直接投屏展示。6.2 兼容性矩阵表证明“不是玩具”老师会怀疑“这只能在你电脑上跑吧” 一张兼容性矩阵比十句解释管用平台Python版本依赖库版本是否支持多屏是否需手动授权备注Windows 10/113.8–3.11mss 9.0.1, opencv-python 4.8.1✅ 合并❌服务模式下无需交互macOS Ventura3.9–3.11pyobjc 10.2, opencv-python 4.8.1✅ 主屏✅ 首次运行权限在“系统设置”中授予Ubuntu 22.043.10mss 9.0.1, opencv-python-headless 4.8.1✅ 合并❌需export DISPLAY:0CentOS 73.6mss 6.1.0旧版, opencv-python 4.5.5✅ 合并❌需提前安装libX11-devel注意CentOS 7的mss必须用6.x因新版依赖libxcb而CentOS 7默认无opencv-python-headless避免GUI依赖适合无桌面环境。6.3 功能完整性检查表确保“不漏项”对照项目需求逐条打钩。这是你答辩时的“检查清单”也是老师提问的“题库”功能点是否实现实现位置验证方式客户端零配置启动双击即运行✅client/start_capture.bat在干净Win10虚拟机中测试服务端集中管理所有客户端列表✅/api/sessions浏览器直接访问返回JSON数组单帧画面实时查看≤1.5s延迟✅/api/frame/{id}Chrome Network Tab 测量TTFB断网后自动重连≤5s✅reconnect_to_relay()ipconfig /release后观察日志支持Mac/Linux/Windows三端✅跨平台代码分支三台实体机同步运行截图日志记录关键事件连接/断开/错误✅logging.info()查看client/logs/和relay/logs/6.4 五分钟演示脚本让答辩变成“现场直播”别念PPT。我让学生准备一个demo.shLinux/Mac或demo.batWindows答辩时双击运行全程5分钟涵盖所有亮点# demo.sh echo 步骤1启动Viewer Server nohup python3 viewer/app.py viewer.log 21 sleep 2 echo 步骤2启动Relay nohup python3 relay/server.py relay.log 21 sleep 2 echo 步骤3启动三台模拟客户端Win/Mac/Linux # 这里启动三个终端分别运行各自平台的采集端 gnome-terminal -- bash -c cd client python3 capture_loop.py; exec bash gnome-terminal -- bash -c cd client python3 capture_loop.py; exec bash # 模拟第二台 gnome-terminal -- bash -c cd client python3 capture_loop.py; exec bash # 模拟第三台 echo 步骤4打开浏览器访问监控面板 xdg-open http://localhost:5000/api/sessions # 自动打开浏览器 echo 步骤5制造一次断线展示自动恢复 pkill -f capture_loop.py sleep 5 echo ✅ 请看/api/sessions中客户端已重新上线后悔药脚本末尾加一句echo 所有日志已保存至 ./logs/可随时复查万一演示翻车立刻切到终端展示日志老师反而觉得你严谨。6.5 两次压力测试用数据代替形容词答辩时说“性能很好”是苍白的。我说“我们做了两次压力测试结果在这里。”第一次单Relay极限测试工具locust模拟200个客户端并发推送结果Relay内存稳定在1.1GBCPU峰值78%无丢帧Viewer Server/api/frame/xxxP95延迟1.3s结论单Relay可支撑2本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑