From 54ee0f7490f75ab55ee1b99a19bae43cae56dc45 Mon Sep 17 00:00:00 2001 From: milk <53408947@qq.com> Date: Fri, 31 Oct 2025 13:19:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=9B=91=E5=90=AC=E6=8A=95?= =?UTF-8?q?=E5=B1=8F=E7=AB=AF=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Module/DeviceInfo.py | 123 +++++++++++------- Module/Main.py | 2 +- Module/__pycache__/DeviceInfo.cpython-312.pyc | Bin 28984 -> 30163 bytes Module/__pycache__/Main.cpython-312.pyc | Bin 3763 -> 3763 bytes Utils/LogManager.py | 2 +- Utils/__pycache__/LogManager.cpython-312.pyc | Bin 14663 -> 14663 bytes .../__pycache__/ScriptManager.cpython-312.pyc | Bin 69564 -> 69569 bytes 7 files changed, 81 insertions(+), 46 deletions(-) diff --git a/Module/DeviceInfo.py b/Module/DeviceInfo.py index bdc9906..7a8ba1f 100644 --- a/Module/DeviceInfo.py +++ b/Module/DeviceInfo.py @@ -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: diff --git a/Module/Main.py b/Module/Main.py index 92de576..11b32b7 100644 --- a/Module/Main.py +++ b/Module/Main.py @@ -50,7 +50,7 @@ if __name__ == "__main__": # 清空日志 LogManager.clearLogs() - main(sys.argv) + # main(sys.argv) # 添加iOS开发包到电脑上 deployer = DevDiskImageDeployer(verbose=True) diff --git a/Module/__pycache__/DeviceInfo.cpython-312.pyc b/Module/__pycache__/DeviceInfo.cpython-312.pyc index 7d2a3487be85ef73c690568779c0d68f94830997..6bf4488d9896597a2b8ded66f4a7f5ffc46824d1 100644 GIT binary patch delta 7434 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 IfXJ2pze(zqfB*mh diff --git a/Module/__pycache__/Main.cpython-312.pyc b/Module/__pycache__/Main.cpython-312.pyc index 497bbf972a4f459d9fc5691876c72e789df16d2e..c670ff135faa0d9dee381486633921d641675c7b 100644 GIT binary patch delta 19 ZcmdliyIGd&G%qg~0}zxaY~)(W2LLl@1mgez delta 19 ZcmdliyIGd&G%qg~0}xDg-^jI+4*)Zt1n2+& diff --git a/Utils/LogManager.py b/Utils/LogManager.py index 3981133..0c8bb94 100644 --- a/Utils/LogManager.py +++ b/Utils/LogManager.py @@ -26,7 +26,7 @@ def _force_utf8_everywhere(): except Exception: pass -_force_utf8_everywhere() +# _force_utf8_everywhere() class LogManager: """ diff --git a/Utils/__pycache__/LogManager.cpython-312.pyc b/Utils/__pycache__/LogManager.cpython-312.pyc index 4b44dc59179ff37bfebb55dbfdbc173dbda35c16..46aff74354ea3a9d22a34436ef457ce5755cf5b9 100644 GIT binary patch delta 19 ZcmX?Jbi9b`G%qg~0}zxaY~-@F1OPzQ1#|!a delta 19 ZcmX?Jbi9b`G%qg~0}xDg-^gWa2>?M11$h7f diff --git a/script/__pycache__/ScriptManager.cpython-312.pyc b/script/__pycache__/ScriptManager.cpython-312.pyc index 5fe13b32793ed0a2542e8cde50081c398ae43da8..402a034da4c1b9f77fc640f51ec133227f72bd11 100644 GIT binary patch delta 371 zcmdlppXK0u7OvC0yj%=Gpb)Z=t1g&Pd-A`j;*%EyyG-6Xfq(K*Zy-CAcd~d0Kc{XB zM=gI1Z;IYz{SfuZJ3{y;r-lSG8f@Mf;>|eOD@=8=W|$(Q(d3$bNg(MkMS5~WSjy!0 z+qovc3sYk>ncNtw2_)^q!zVurH=La9D?d3Z!f>*9gfpZ0X9VRPAnKC*~ z4v*4?S}8txag-xa&pJmT{7OvC0yj%=GuvBv+S6%Sr1);o?d;8=k*M)LU-W#mWuARcv$+((%@?LLw zu$*`ZKc`L$M=gI1Z;I|@{Sb9Vy~*JriIc-Z_%|O9v1OdRBZPl)e?K>)!DRU`?a3@* zs*_*$3r=nbOJOvc{4`9T(RgxWtR|4O4-aQFnH(KqI622xZt}En!^z?i&Xb=3>Fx-1 zR`XhsJln|+{p1-ffNK1>QY3LVnDY2WW^{`Mu*AaQQEvls~JIl1ezdNBRKitB=O11qU^XGYQ!oSiiLNGrEGk;W|0i zSC`YRhG{m#T&5KF$^Nm@%pR*5CkKWJPtJP~zeWwaNdz zye7xT*G_&D$1^!9jBE0pc<#xm)7>XG^b1VpmE)Qmmr%gyxA}a+e%8&C)AUvX0J%?$ AcmMzZ