阶段2: USB 远程 adb server 打通(220 host 网络 5037 全接口监听,无需改 220)+ 自建远程看屏(MJPEG 流 + u2 触控 tap/swipe/key/text,ws-scrcpy 不在 npm 改自建)

This commit is contained in:
2026-08-17 16:50:12 +08:00
parent 5354fe6379
commit 645938b305
10 changed files with 466 additions and 50 deletions
+37 -9
View File
@@ -32,7 +32,7 @@ from core.logger import get_logger
from core.models import db, DeviceGroup as GroupRow, TaskJob as JobRow
from core import device_pool
from .stf_client import STFClient, DeviceOfflineError
from .adb_helper import get_foreground_app, adb_connect_light, adb_disconnect
from .adb_helper import get_foreground_app, get_foreground_app_remote
from .device_worker import (
get_all_worker_status, _update_status, _remove_worker,
_WORKERS, _WORKERS_LOCK,
@@ -260,22 +260,26 @@ class _ForegroundScanner:
worker_status = {w["serial"]: w for w in get_all_worker_status()}
# 分类设备
have_conn = {} # serial -> remote_adb_url(worker 运行中,已有 adb 连接)
have_conn = {} # serial -> remote_adb_url(IP:5555 运行中设备)
usb_conn = {} # serial -> usb_server(USB 运行中设备,经远程 adb server)
free_serials = [] # 空闲设备
for serial in online:
w = worker_status.get(serial, {})
url = w.get("remote_adb_url")
if url and w.get("status") in ("running", "connecting"):
# 1. 设备正在执行任务,已有 adb 连接,直接查询
have_conn[serial] = url
if w.get("status") not in ("running", "connecting"):
free_serials.append(serial)
elif w.get("remote_adb_url"):
# 1. IP:5555 设备正在执行任务,已有 adb 连接,直接查询
have_conn[serial] = w["remote_adb_url"]
elif w.get("usb_server"):
# 1b. USB 设备运行中:经远程 adb server 查询
usb_conn[serial] = w["usb_server"]
else:
# 2. 空闲设备
free_serials.append(serial)
results = {}
_log.info("前台 App 扫描分类: 运行中=%d, 空闲=%d",
len(have_conn), len(free_serials))
_log.info("前台 App 扫描分类: 运行中=%d, USB运行中=%d, 空闲=%d",
len(have_conn), len(usb_conn), len(free_serials))
# 1. worker 运行中设备:用已有 remote_adb_url 查询(并发 10)
if have_conn:
@@ -289,6 +293,18 @@ class _ForegroundScanner:
except Exception:
results[s] = None
# 1b. USB 运行中设备:经远程 adb server 查询(并发 5)
if usb_conn:
with ThreadPoolExecutor(max_workers=min(5, len(usb_conn))) as pool:
futures = {pool.submit(self._scan_usb_conn, s): s
for s, server in usb_conn.items()}
for fut in as_completed(futures, timeout=15):
s = futures[fut]
try:
results[s] = fut.result()
except Exception:
results[s] = None
# 2. 空闲设备:不打扰,直接返回"空闲"
for s in free_serials:
results[s] = "空闲"
@@ -303,6 +319,18 @@ class _ForegroundScanner:
self._scanning.clear()
_log.info("前台 App 扫描完成: %d 台设备", len(results))
def _scan_usb_conn(self, serial):
"""USB 运行中设备:经远程 adb server(220)查询前台 App。"""
try:
with _WORKERS_LOCK:
server = _WORKERS.get(serial, {}).get("usb_server", "")
if not server:
return None
host, _, port = server.partition(":")
return get_foreground_app_remote(host, int(port), serial)
except Exception:
return None
# ================== 任务管理器 ==================
class TaskManager: