增加监听投屏端口
This commit is contained in:
@@ -10,7 +10,7 @@ import threading
|
|||||||
import subprocess
|
import subprocess
|
||||||
import socket
|
import socket
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional, List, Any
|
||||||
import platform
|
import platform
|
||||||
import psutil
|
import psutil
|
||||||
import http.client
|
import http.client
|
||||||
@@ -116,45 +116,62 @@ class DeviceInfo:
|
|||||||
self._iproxy_path = self._find_iproxy()
|
self._iproxy_path = self._find_iproxy()
|
||||||
LogManager.info("DeviceInfo 初始化完成", udid="system")
|
LogManager.info("DeviceInfo 初始化完成", udid="system")
|
||||||
print("[Init] DeviceInfo 初始化完成")
|
print("[Init] DeviceInfo 初始化完成")
|
||||||
# 延迟执行删除设备方法
|
|
||||||
threading.Thread(target=self.readdDevice).start()
|
|
||||||
|
|
||||||
# 清空所有设备
|
threading.Thread(target=self.check_iproxy_ports).start()
|
||||||
def readdDevice(self):
|
|
||||||
print("开始自动删除设备")
|
|
||||||
second = 0
|
# =============== 核心:端口连通性检测 =================
|
||||||
|
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:
|
while True:
|
||||||
second += 1
|
snapshot = list(self._models.items()) # [(deviceId, DeviceModel), ...]
|
||||||
if second == 3555:
|
for device_id, model in snapshot:
|
||||||
with self._lock:
|
try:
|
||||||
# 先拍一张快照,避免“边遍历边修改”
|
# 只处理在线且端口合法的设备
|
||||||
udids = list(self._models.keys())
|
if model.type != 1:
|
||||||
for udid in udids:
|
continue
|
||||||
print(f"[Remove] 正在移除设备 {udid}")
|
port = int(model.screenPort)
|
||||||
# 以 udid 为主键,逐个 pop
|
if port <= 0 or port > 65535:
|
||||||
model = self._models.pop(udid, None)
|
continue
|
||||||
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)
|
|
||||||
|
|
||||||
|
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):
|
def listen(self):
|
||||||
LogManager.method_info("进入主循环", "listen", udid="system")
|
LogManager.method_info("进入主循环", "listen", udid="system")
|
||||||
@@ -242,10 +259,7 @@ class DeviceInfo:
|
|||||||
if not self._wda_http_status_ok_once(udid):
|
if not self._wda_http_status_ok_once(udid):
|
||||||
if major > 17:
|
if major > 17:
|
||||||
print("进入iOS17设备的分支")
|
print("进入iOS17设备的分支")
|
||||||
print(f"[WDA] iOS>17 调用 IOSActivator (port={wdaScreenPort})")
|
|
||||||
print("准备启动隧道")
|
|
||||||
out = IOSActivator().activate(udid)
|
out = IOSActivator().activate(udid)
|
||||||
print("------------------",out)
|
|
||||||
print("wda启动完成")
|
print("wda启动完成")
|
||||||
else:
|
else:
|
||||||
print(f"[WDA] iOS<=17 启动 WDA app_start (port={wdaScreenPort})")
|
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}")
|
print(f"[Add] 设备添加成功 {udid}, port={port}, {w}x{h}@{s}")
|
||||||
|
|
||||||
def _remove_device(self, udid: str):
|
def _remove_device(self, udid: str):
|
||||||
method = "_remove_device"
|
"""
|
||||||
|
移除设备及其转发,通知上层。
|
||||||
|
幂等:重复调用不会出错。
|
||||||
|
"""
|
||||||
print(f"[Remove] 正在移除设备 {udid}")
|
print(f"[Remove] 正在移除设备 {udid}")
|
||||||
|
|
||||||
|
# --- 1. 锁内执行所有轻量字典操作 ---
|
||||||
with self._lock:
|
with self._lock:
|
||||||
model = self._models.pop(udid, None)
|
model = self._models.pop(udid, None)
|
||||||
proc = self._iproxy.pop(udid, None)
|
proc = self._iproxy.pop(udid, None)
|
||||||
@@ -302,14 +321,30 @@ class DeviceInfo:
|
|||||||
self._first_seen.pop(udid, None)
|
self._first_seen.pop(udid, None)
|
||||||
self._last_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:
|
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.type = 2
|
||||||
model.ready = False
|
model.ready = False
|
||||||
model.screenPort = -1
|
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}")
|
print(f"[Remove] 设备移除完成 {udid}")
|
||||||
|
|
||||||
def _trusted(self, udid: str) -> bool:
|
def _trusted(self, udid: str) -> bool:
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ if __name__ == "__main__":
|
|||||||
# 清空日志
|
# 清空日志
|
||||||
LogManager.clearLogs()
|
LogManager.clearLogs()
|
||||||
|
|
||||||
main(sys.argv)
|
# main(sys.argv)
|
||||||
|
|
||||||
# 添加iOS开发包到电脑上
|
# 添加iOS开发包到电脑上
|
||||||
deployer = DevDiskImageDeployer(verbose=True)
|
deployer = DevDiskImageDeployer(verbose=True)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -26,7 +26,7 @@ def _force_utf8_everywhere():
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
_force_utf8_everywhere()
|
# _force_utf8_everywhere()
|
||||||
|
|
||||||
class LogManager:
|
class LogManager:
|
||||||
"""
|
"""
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user