Files
iOSAI/Module/Main.py

119 lines
3.6 KiB
Python
Raw Normal View History

import asyncio
2025-10-23 18:53:22 +08:00
# ===== Main.py 顶部放置(所有 import 之前)=====
2025-08-15 20:04:59 +08:00
import os
import sys
from pathlib import Path
from asgiref.wsgi import WsgiToAsgi
from Utils.AiUtils import AiUtils
2025-10-29 16:56:34 +08:00
from Utils.LogManager import LogManager
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
2025-10-29 16:56:34 +08:00
2025-10-23 18:53:22 +08:00
if "IOSAI_PYTHON" not in os.environ:
base_path = Path(sys.argv[0]).resolve()
base_dir = base_path.parent if base_path.is_file() else base_path
sidecar = base_dir / "python-rt" / ("python.exe" if os.name == "nt" else "python")
if sidecar.exists():
os.environ["IOSAI_PYTHON"] = str(sidecar)
# ==============================================
2025-08-15 20:04:59 +08:00
# 确定 exe 或 py 文件所在目录
BASE = Path(getattr(sys, 'frozen', False) and sys.executable or __file__).resolve().parent
LOG_DIR = BASE / "log"
LOG_DIR.mkdir(exist_ok=True) # 确保 log 目录存在
print(f"日志目录: {LOG_DIR}")
def _run_flask_role():
2025-11-07 16:31:18 +08:00
from Module.FlaskService import get_app, bootstrap_server_side_effects
2025-11-06 21:50:28 +08:00
print("Flask Pid:", os.getpid())
2025-10-29 16:56:34 +08:00
port = int(os.getenv("FLASK_COMM_PORT", "34566")) # 固定端口的兜底仍是 34567
2025-11-07 16:31:18 +08:00
app = get_app()
flaskPort = port + 1
AiUtils.flask_port_free(flaskPort)
2025-11-07 16:31:18 +08:00
bootstrap_server_side_effects()
# 把 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))
2025-08-15 20:04:59 +08:00
if "--role=flask" in sys.argv:
_run_flask_role()
sys.exit(0)
2025-10-29 16:56:34 +08:00
# 启动锁
2025-09-24 16:32:05 +08:00
def main(arg):
2025-10-29 16:56:34 +08:00
if len(arg) != 2 or arg[1] != "iosai":
2025-09-24 16:32:05 +08:00
sys.exit(0)
2025-09-04 20:47:14 +08:00
2025-08-11 22:06:48 +08:00
# 项目入口
2025-08-01 13:43:51 +08:00
if __name__ == "__main__":
2025-09-04 20:47:14 +08:00
2025-10-29 16:56:34 +08:00
# 清空日志
2025-11-07 14:31:07 +08:00
LogManager.clearLogs()
2025-10-29 16:56:34 +08:00
main(sys.argv)
2025-09-23 20:17:33 +08:00
2025-08-28 16:02:28 +08:00
# 添加iOS开发包到电脑上
2025-08-28 15:46:17 +08:00
deployer = DevDiskImageDeployer(verbose=True)
deployer.deploy_all()
2025-08-06 22:11:33 +08:00
2025-08-15 20:04:59 +08:00
# 启动 Flask 子进程
2025-08-01 13:43:51 +08:00
manager = FlaskSubprocessManager.get_instance()
manager.start()
2025-08-15 20:04:59 +08:00
# 设备监听(即使失败/很快返回,也不会导致主进程退出)
2025-09-22 14:36:05 +08:00
try:
info = DeviceInfo()
info.listen()
except Exception as e:
print("[WARN] Device listener not running:", e)
2025-08-15 20:04:59 +08:00
# === 保活:阻塞主线程,直到收到 Ctrl+C/关闭 ===
import threading, time, signal
stop = threading.Event()
def _handle(_sig, _frm):
stop.set()
2025-09-24 16:32:05 +08:00
2025-08-15 20:04:59 +08:00
# Windows 上 SIGINT/SIGTERM 都可以拦到
try:
signal.signal(signal.SIGINT, _handle)
signal.signal(signal.SIGTERM, _handle)
except Exception:
pass # 某些环境可能不支持,忽略
try:
while not stop.is_set():
time.sleep(1)
finally:
# 进程退出前记得把子进程关掉
manager.stop()
2025-11-07 16:31:18 +08:00