增加flask启动端口检测,增加H2协议的支持。
This commit is contained in:
@@ -317,7 +317,7 @@ def deviceList():
|
||||
@app.route('/passToken', methods=['POST'])
|
||||
def passToken():
|
||||
data = request.get_json()
|
||||
print(data)
|
||||
print(json.dumps(data))
|
||||
return ResultData(data="").toJson()
|
||||
|
||||
# 获取设备应用列表
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
|
||||
import asyncio
|
||||
# ===== Main.py 顶部放置(所有 import 之前)=====
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from asgiref.wsgi import WsgiToAsgi
|
||||
|
||||
from Utils.AiUtils import AiUtils
|
||||
from Utils.LogManager import LogManager
|
||||
import logging
|
||||
from hypercorn.asyncio import serve
|
||||
from hypercorn.config import Config
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from Module.DeviceInfo import DeviceInfo
|
||||
from Module.FlaskSubprocessManager import FlaskSubprocessManager
|
||||
from Utils.DevDiskImageDeployer import DevDiskImageDeployer
|
||||
|
||||
if "IOSAI_PYTHON" not in os.environ:
|
||||
base_path = Path(sys.argv[0]).resolve()
|
||||
@@ -14,13 +24,6 @@ if "IOSAI_PYTHON" not in os.environ:
|
||||
os.environ["IOSAI_PYTHON"] = str(sidecar)
|
||||
# ==============================================
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from Module.DeviceInfo import DeviceInfo
|
||||
from Module.FlaskSubprocessManager import FlaskSubprocessManager
|
||||
from Utils.DevDiskImageDeployer import DevDiskImageDeployer
|
||||
|
||||
# 确定 exe 或 py 文件所在目录
|
||||
BASE = Path(getattr(sys, 'frozen', False) and sys.executable or __file__).resolve().parent
|
||||
LOG_DIR = BASE / "log"
|
||||
@@ -33,8 +36,32 @@ def _run_flask_role():
|
||||
print("Flask Pid:", os.getpid())
|
||||
port = int(os.getenv("FLASK_COMM_PORT", "34566")) # 固定端口的兜底仍是 34567
|
||||
app = get_app()
|
||||
flaskPort = port + 1
|
||||
AiUtils.flask_port_free(flaskPort)
|
||||
bootstrap_server_side_effects()
|
||||
app.run(host="0.0.0.0", port=port + 1, debug=False, use_reloader=False, threaded=True)
|
||||
|
||||
# 把 WSGI Flask app 包成 ASGI app
|
||||
asgi_app = WsgiToAsgi(app)
|
||||
|
||||
# Hypercorn 配置
|
||||
# 自动定位 resources 目录
|
||||
base_dir = os.path.dirname(os.path.abspath(__file__)) # 当前 py 的目录(Module/)
|
||||
project_root = os.path.dirname(base_dir) # 回到项目根目录(iOSAi/)
|
||||
resource_dir = os.path.join(project_root, "resources") # 拼到 resources
|
||||
|
||||
config = Config()
|
||||
config.bind = [f"0.0.0.0:{flaskPort}"]
|
||||
config.alpn_protocols = ["h2"] # 开 HTTP/2
|
||||
config.certfile = os.path.join(resource_dir, "cert.pem")
|
||||
config.keyfile = os.path.join(resource_dir, "key.pem")
|
||||
|
||||
print(f"Starting Hypercorn on port {flaskPort} (HTTP/2 enabled)")
|
||||
|
||||
# 开启 HTTP/2
|
||||
config.alpn_protocols = ["h2"]
|
||||
|
||||
print(f"Starting Hypercorn on https://localhost:{flaskPort} (HTTP/2 enabled)")
|
||||
asyncio.run(serve(asgi_app, config))
|
||||
|
||||
if "--role=flask" in sys.argv:
|
||||
_run_flask_role()
|
||||
@@ -51,7 +78,7 @@ if __name__ == "__main__":
|
||||
# 清空日志
|
||||
LogManager.clearLogs()
|
||||
|
||||
# main(sys.argv)
|
||||
main(sys.argv)
|
||||
|
||||
# 添加iOS开发包到电脑上
|
||||
deployer = DevDiskImageDeployer(verbose=True)
|
||||
|
||||
@@ -2,7 +2,11 @@ import html
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import signal
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import xml.etree.ElementTree as ET
|
||||
from pathlib import Path
|
||||
import cv2
|
||||
@@ -62,6 +66,56 @@ class AiUtils(object):
|
||||
# print(e)
|
||||
# return -1, -1
|
||||
|
||||
@classmethod
|
||||
def flask_port_free(cls,port):
|
||||
"""无需 psutil 的版本,通过系统命令查 PID"""
|
||||
|
||||
def can_bind(p):
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
s.bind(("0.0.0.0", p))
|
||||
s.close()
|
||||
return True
|
||||
except OSError:
|
||||
s.close()
|
||||
return False
|
||||
|
||||
if can_bind(port):
|
||||
return
|
||||
|
||||
print(f"[ensure_port_free] Port {port} is occupied. Searching PID...")
|
||||
|
||||
pids = set()
|
||||
|
||||
if sys.platform.startswith("darwin") or sys.platform.startswith("linux"):
|
||||
cmd = f"lsof -t -i:{port}"
|
||||
proc = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
for line in proc.stdout.splitlines():
|
||||
if line.strip().isdigit():
|
||||
pids.add(int(line.strip()))
|
||||
|
||||
elif sys.platform.startswith("win"):
|
||||
cmd = f"netstat -ano | findstr :{port}"
|
||||
proc = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
for line in proc.stdout.splitlines():
|
||||
parts = line.split()
|
||||
if len(parts) >= 5 and parts[-1].isdigit():
|
||||
pids.add(int(parts[-1]))
|
||||
|
||||
else:
|
||||
raise RuntimeError("Unsupported platform for ensure_port_free")
|
||||
|
||||
for pid in pids:
|
||||
try:
|
||||
print(f"[ensure_port_free] Killing PID {pid}...")
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
except Exception as e:
|
||||
print(f"[ensure_port_free] Failed to kill PID {pid}: {e}")
|
||||
|
||||
time.sleep(0.3)
|
||||
if not can_bind(port):
|
||||
raise RuntimeError(f"[ensure_port_free] Port {port} still occupied after kill.")
|
||||
|
||||
@classmethod
|
||||
def findImageInScreen(cls, target, udid):
|
||||
try:
|
||||
|
||||
@@ -26,7 +26,7 @@ def _force_utf8_everywhere():
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# _force_utf8_everywhere()
|
||||
_force_utf8_everywhere()
|
||||
|
||||
class LogManager:
|
||||
"""
|
||||
|
||||
@@ -9,7 +9,7 @@ python -m nuitka Module\Main.py ^
|
||||
--windows-console-mode=disable ^
|
||||
--output-filename=IOSAI ^
|
||||
--include-package=Module,Utils,Entity,script ^
|
||||
--include-module=flask,wda,psutil,portalocker,flask_cors,cv2,lxml.etree,requests,urllib3,certifi,idna,setuptools ^
|
||||
--include-module=flask,wda,psutil,portalocker,flask_cors,cv2,lxml.etree,requests,urllib3,certifi,idna,setuptools,asgiref,hypercorn,h2,hpack,wsproto,priority,anyio,sniffio ^
|
||||
--include-data-dir=resources=resources ^
|
||||
--include-data-dir=SupportFiles=SupportFiles ^
|
||||
--include-data-files="resources/iproxy/*=resources/iproxy/" ^
|
||||
|
||||
21
resources/cert.pem
Normal file
21
resources/cert.pem
Normal file
@@ -0,0 +1,21 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDizCCAnOgAwIBAgIUXpRsBS0IBEvAw22Ii/wtu/gdooUwDQYJKoZIhvcNAQEL
|
||||
BQAwXTELMAkGA1UEBhMCQ04xDjAMBgNVBAgMBUxvY2FsMQ4wDAYDVQQHDAVMb2Nh
|
||||
bDEMMAoGA1UECgwDRGV2MQwwCgYDVQQLDANEZXYxEjAQBgNVBAMMCWxvY2FsaG9z
|
||||
dDAeFw0yNTExMTcwODI2MzdaFw0yNjExMTcwODI2MzdaMF0xCzAJBgNVBAYTAkNO
|
||||
MQ4wDAYDVQQIDAVMb2NhbDEOMAwGA1UEBwwFTG9jYWwxDDAKBgNVBAoMA0RldjEM
|
||||
MAoGA1UECwwDRGV2MRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQCixGQJ0gdzcQoqdOv4lLvfH5Kz4C/t4/WCZfheF3Z7
|
||||
cYiog0Ql8URyn6bF8ux97X4TtpJ621jM/lfxc2hKrqXpbsyO2EKgT3OEpuv/lyqC
|
||||
YQqbHUUIAiXI9OF/iAANY5rBIeEDEUhcH4Ngt6EJ1FZdU+tfgV8V9zNUSeSJ+VtF
|
||||
C+0LsTyWy7eqnXkXnPZvitVeZU85Zy5lWdC1mp9cOoyElmYuGxIQkW6ZtEzMjVp4
|
||||
Eim3RsZgk6ZYRAdMGfdaa6YrmDDqhEZVEEL55dstOqfIWKUppazC9HSs7FnGsaUn
|
||||
xkdqOArACdhU9y3f+yyeLC93Xllx9kgFfvLueysUqSgdAgMBAAGjQzBBMCAGA1Ud
|
||||
EQQZMBeCCWxvY2FsaG9zdIcEfwAAAYcEwKgB2jAdBgNVHQ4EFgQURY1BDcpSTUNO
|
||||
D0olM9H84Gu/QQ0wDQYJKoZIhvcNAQELBQADggEBAFrCAqIlpzncH6owBImN8Ub5
|
||||
8ZwtTm+C3nQZF5FkCdsXHfqtPTEk4bX7IFHaj7saqroCYXfgopzvk2QX16wlPwk2
|
||||
SKA/pF6I2bNNozlcVN9QAf9ue6xa8g8AxwPT46gbKTKFyG5lg1umYXhCGKVIJ/1l
|
||||
B4Bh8KmPfzNWxiKOzflGNx5j1BHPZ9S7jt9wtiEwENceGZXVE8ANMiNR44+suuM7
|
||||
6/syQUetPN+VWW+/14OrDeYQDLZTbUVigY75KIuLF41PxNWG745Qlcu/5nmvBnHv
|
||||
5NNm2Zs8GYKLqLIlUQNU8x0R03FBLCYjDKRJsNpsZPqjI5cDSPj5vHZrzD3Jh0s=
|
||||
-----END CERTIFICATE-----
|
||||
28
resources/key.pem
Normal file
28
resources/key.pem
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCixGQJ0gdzcQoq
|
||||
dOv4lLvfH5Kz4C/t4/WCZfheF3Z7cYiog0Ql8URyn6bF8ux97X4TtpJ621jM/lfx
|
||||
c2hKrqXpbsyO2EKgT3OEpuv/lyqCYQqbHUUIAiXI9OF/iAANY5rBIeEDEUhcH4Ng
|
||||
t6EJ1FZdU+tfgV8V9zNUSeSJ+VtFC+0LsTyWy7eqnXkXnPZvitVeZU85Zy5lWdC1
|
||||
mp9cOoyElmYuGxIQkW6ZtEzMjVp4Eim3RsZgk6ZYRAdMGfdaa6YrmDDqhEZVEEL5
|
||||
5dstOqfIWKUppazC9HSs7FnGsaUnxkdqOArACdhU9y3f+yyeLC93Xllx9kgFfvLu
|
||||
eysUqSgdAgMBAAECggEAGY29qvEHbG9Vyj6bAWbQbAI39PeAbte4JqW9rX//gPfd
|
||||
HZ+mJlLPjTNVaoRt7oNHpO6n5pPjSCOySNz2hasPrytPACoho6t1lmDicjkYWmnD
|
||||
0YBx4wT7S6ZudKg0YeW+WQ3plqKy+ouUA64woStt968CJ/dWp0stCtGjCKpWUuuB
|
||||
TXvAUM91qrQlpIuqQI0QYRcKaoKPV6IckWPGeLvKi8EhVOFCNdya8jTP/ayxT06r
|
||||
/cNucO+Tqe0PUe6jet6Ecx7Av4h8QXg9FMoF40RKxD6Q+sK/bM1c51KvUZVt9v4F
|
||||
epAHjQyrzPjUozjtKzQvibexBvSwz/XaFCDgr7OwPQKBgQDOJtILcxjJDZfk8LUG
|
||||
GNF8XVtgDu2FFVw79MSuQgERC+w2b+P2feffwdI4vu2+8jkWCHnttXNgdrS3r41C
|
||||
gak3Xb2Jzx8M06eNC9QCtjicrWNTmJtcp5YZm1vS+fAPQG4DPLK+J4EmLNNyQ9nC
|
||||
0vMfYRwKr3TX5FU6MyJbAsVnkwKBgQDKH/zUhMPdN6+0upEVoUJrI3BOhVdN8eEp
|
||||
eqNWYU2Hhmg5mHsnoxz8Rjxw5ZKx108BT1JNea/rrNgOhe8TTpiAIVl5ZMN0OcO2
|
||||
INlfteCtXY5nzU8HilfFBPwroR8Msx662GpM8TRA9RfTGJ7nKmiXhC1jnmkPecwX
|
||||
+f+LaLCfjwKBgQC11H3dxXYuF8RLFZjFuOxFIl7vOht8D9wbsggsn2ErdPWzCjvq
|
||||
9SCpNt7CWH2At0tsyKsq5KnQgsNhZQFWkOD9SbxdKgf8G0+k07L7dVg3saNzX55h
|
||||
OhvlmCeEzhlUioK+bjJGELgUQON73Kbc9Y2lttSyBBIuPmKCBAogdjBB6wKBgGnM
|
||||
VIro85zXiSEQhuDLh/iMlDyFjy09bp5HkzejtvE5aVS8e7pDpuhl2z087YwpJzGI
|
||||
U4w6Jds2neD8Oifg+/IVgsAH/kbX9ZlfmGiAyxnz3pZ24OcRgt+dvGEZ9Sawm2Ux
|
||||
4nJjzvYxVEcqnAJkMFse1KNQR63SEwJ52Ukfg1QBAoGBAKByisJiMTi/gmSlPFf6
|
||||
3ZfxCd5ReMS/Ak4JIBN4S+GoAZp6yMZy1jYFHqV2k3slhmcswy+V9DGxtldHlDu9
|
||||
+90zV1btfaB3nq5ydkmj32SU9MRqpzP4axHYTi8cvmOBlOEpL5e7KWTg072rGHAC
|
||||
+ih8VPn9LTKk2GCtCCp4r2jI
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -669,11 +669,7 @@ class ScriptManager():
|
||||
event.wait(timeout=2)
|
||||
|
||||
session.appium_settings({"snapshotMaxDepth": 12})
|
||||
|
||||
LogManager.method_info(f"检查当前是否为视频页面", "关注打招呼", udid)
|
||||
|
||||
is_back_enabled = ControlUtils.isClickBackEnabled(session)
|
||||
|
||||
# 最多尝试 3 次(第一次 + 再试两次)
|
||||
for attempt in range(3):
|
||||
is_back_enabled = ControlUtils.isClickBackEnabled(session)
|
||||
|
||||
Reference in New Issue
Block a user