增加监听投屏端口
This commit is contained in:
@@ -10,7 +10,7 @@ import threading
|
||||
import subprocess
|
||||
import socket
|
||||
from pathlib import Path
|
||||
from typing import Dict, Optional
|
||||
from typing import Dict, Optional, List, Any
|
||||
import platform
|
||||
import psutil
|
||||
import http.client
|
||||
@@ -116,45 +116,62 @@ class DeviceInfo:
|
||||
self._iproxy_path = self._find_iproxy()
|
||||
LogManager.info("DeviceInfo 初始化完成", udid="system")
|
||||
print("[Init] DeviceInfo 初始化完成")
|
||||
# 延迟执行删除设备方法
|
||||
threading.Thread(target=self.readdDevice).start()
|
||||
|
||||
# 清空所有设备
|
||||
def readdDevice(self):
|
||||
print("开始自动删除设备")
|
||||
second = 0
|
||||
threading.Thread(target=self.check_iproxy_ports).start()
|
||||
|
||||
|
||||
# =============== 核心:端口连通性检测 =================
|
||||
def _is_local_port_open(self, port: int,udid:str, timeout: float = 5) -> bool:
|
||||
print("开始监听剪口")
|
||||
"""
|
||||
Windows: 尝试连接 127.0.0.1:port,能连上即认为端口可用(iproxy 正在监听/转发)。
|
||||
不抛异常,返回 True/False。
|
||||
"""
|
||||
if not isinstance(port, int) or port <= 0 or port > 65535:
|
||||
LogManager.error("端口不可用",udid=udid)
|
||||
return False
|
||||
|
||||
try:
|
||||
print("尝试监听")
|
||||
# create_connection 会在连接成功时立即返回 socket
|
||||
with socket.create_connection(("127.0.0.1", int(port)), timeout=timeout):
|
||||
print("端口正常")
|
||||
return True
|
||||
except OSError:
|
||||
LogManager.error("端口不可用",udid=udid)
|
||||
return False
|
||||
|
||||
# =============== 一轮检查:发现不通就移除 =================
|
||||
def check_iproxy_ports(self, connect_timeout: float = 3) -> None:
|
||||
time.sleep(60)
|
||||
print("开始监听投屏端口")
|
||||
while True:
|
||||
second += 1
|
||||
if second == 3555:
|
||||
with self._lock:
|
||||
# 先拍一张快照,避免“边遍历边修改”
|
||||
udids = list(self._models.keys())
|
||||
for udid in udids:
|
||||
print(f"[Remove] 正在移除设备 {udid}")
|
||||
# 以 udid 为主键,逐个 pop
|
||||
model = self._models.pop(udid, None)
|
||||
proc = self._iproxy.pop(udid, None)
|
||||
self._port_by_udid.pop(udid, None)
|
||||
self._first_seen.pop(udid, None)
|
||||
self._last_seen.pop(udid, None)
|
||||
# 安全结束进程
|
||||
self._kill(proc)
|
||||
# 组一个“下线通知”的占位模型
|
||||
if model is None:
|
||||
model = DeviceModel(
|
||||
deviceId=udid, screenPort=-1, width=0, height=0, scale=0.0, type=2
|
||||
)
|
||||
# 标记为“已移除/离线”
|
||||
model.type = 2
|
||||
model.ready = False
|
||||
model.screenPort = -1
|
||||
# 通知上层
|
||||
self._manager_send(model)
|
||||
print(f"[Remove] 已移除设备 {udid}")
|
||||
second = 0
|
||||
print(f"[Remove] 设备移除完成,总数: {len(udids)}")
|
||||
time.sleep(1)
|
||||
snapshot = list(self._models.items()) # [(deviceId, DeviceModel), ...]
|
||||
for device_id, model in snapshot:
|
||||
try:
|
||||
# 只处理在线且端口合法的设备
|
||||
if model.type != 1:
|
||||
continue
|
||||
port = int(model.screenPort)
|
||||
if port <= 0 or port > 65535:
|
||||
continue
|
||||
|
||||
ok = self._is_local_port_open(port, timeout=connect_timeout, udid=device_id)
|
||||
if not ok:
|
||||
print(f"[iproxy-check] 端口不可连,移除设备 deviceId={device_id} port={port}")
|
||||
try:
|
||||
self._remove_device(device_id) # 这里面可安全地改 self._models
|
||||
except Exception as e:
|
||||
print(f"[iproxy-check] _remove_device 异常 deviceId={device_id}: {e}")
|
||||
else:
|
||||
# 心跳日志按需开启,避免刷屏
|
||||
# print(f"[iproxy-check] OK deviceId={device_id} port={port}")
|
||||
pass
|
||||
|
||||
except Exception as e:
|
||||
print(f"[iproxy-check] 单设备检查异常: {e}")
|
||||
# 8秒间隔
|
||||
time.sleep(10)
|
||||
|
||||
def listen(self):
|
||||
LogManager.method_info("进入主循环", "listen", udid="system")
|
||||
@@ -242,10 +259,7 @@ class DeviceInfo:
|
||||
if not self._wda_http_status_ok_once(udid):
|
||||
if major > 17:
|
||||
print("进入iOS17设备的分支")
|
||||
print(f"[WDA] iOS>17 调用 IOSActivator (port={wdaScreenPort})")
|
||||
print("准备启动隧道")
|
||||
out = IOSActivator().activate(udid)
|
||||
print("------------------",out)
|
||||
print("wda启动完成")
|
||||
else:
|
||||
print(f"[WDA] iOS<=17 启动 WDA app_start (port={wdaScreenPort})")
|
||||
@@ -293,8 +307,13 @@ class DeviceInfo:
|
||||
print(f"[Add] 设备添加成功 {udid}, port={port}, {w}x{h}@{s}")
|
||||
|
||||
def _remove_device(self, udid: str):
|
||||
method = "_remove_device"
|
||||
"""
|
||||
移除设备及其转发,通知上层。
|
||||
幂等:重复调用不会出错。
|
||||
"""
|
||||
print(f"[Remove] 正在移除设备 {udid}")
|
||||
|
||||
# --- 1. 锁内执行所有轻量字典操作 ---
|
||||
with self._lock:
|
||||
model = self._models.pop(udid, None)
|
||||
proc = self._iproxy.pop(udid, None)
|
||||
@@ -302,14 +321,30 @@ class DeviceInfo:
|
||||
self._first_seen.pop(udid, None)
|
||||
self._last_seen.pop(udid, None)
|
||||
|
||||
self._kill(proc)
|
||||
# --- 2. 锁外执行重操作 ---
|
||||
# 杀进程
|
||||
try:
|
||||
self._kill(proc)
|
||||
except Exception as e:
|
||||
print(f"[Remove] 杀进程异常 {udid}: {e}")
|
||||
|
||||
# 准备下线模型(model 可能为 None)
|
||||
if model is None:
|
||||
model = DeviceModel(deviceId=udid, screenPort=-1, width=0, height=0, scale=0.0, type=2)
|
||||
model = DeviceModel(
|
||||
deviceId=udid, screenPort=-1, width=0, height=0, scale=0.0, type=2
|
||||
)
|
||||
|
||||
# 标记状态为离线
|
||||
model.type = 2
|
||||
model.ready = False
|
||||
model.screenPort = -1
|
||||
self._manager_send(model)
|
||||
|
||||
# 通知上层
|
||||
try:
|
||||
self._manager_send(model)
|
||||
except Exception as e:
|
||||
print(f"[Remove] 通知上层异常 {udid}: {e}")
|
||||
|
||||
print(f"[Remove] 设备移除完成 {udid}")
|
||||
|
||||
def _trusted(self, udid: str) -> bool:
|
||||
|
||||
@@ -50,7 +50,7 @@ if __name__ == "__main__":
|
||||
# 清空日志
|
||||
LogManager.clearLogs()
|
||||
|
||||
main(sys.argv)
|
||||
# main(sys.argv)
|
||||
|
||||
# 添加iOS开发包到电脑上
|
||||
deployer = DevDiskImageDeployer(verbose=True)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -26,7 +26,7 @@ def _force_utf8_everywhere():
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
_force_utf8_everywhere()
|
||||
# _force_utf8_everywhere()
|
||||
|
||||
class LogManager:
|
||||
"""
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user