From b34215560ca22700d0b55e807124dc9d28f47c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B6=B5=E6=9B=A6?= Date: Tue, 30 Jul 2024 01:11:13 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B0=9D=E8=AF=95=E5=8A=A0=E4=B8=AA?= =?UTF-8?q?=E7=BD=91=E5=85=B3=E5=9C=A8=E5=89=8D=E9=9D=A2=E5=A4=84=E7=90=86?= =?UTF-8?q?=E9=9D=99=E6=80=81=E6=96=87=E4=BB=B6=E6=9D=A5=E5=8A=A0=E9=80=9F?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xiaomusic/cli.py | 67 ++++++++++++++++++++++++++++++++++------ xiaomusic/gate.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 9 deletions(-) create mode 100644 xiaomusic/gate.py diff --git a/xiaomusic/cli.py b/xiaomusic/cli.py index 89c9a75..ae86161 100644 --- a/xiaomusic/cli.py +++ b/xiaomusic/cli.py @@ -1,5 +1,8 @@ #!/usr/bin/env python3 import argparse +import json +import os +import signal import uvicorn @@ -75,9 +78,6 @@ def main(): options = parser.parse_args() config = Config.from_options(options) - xiaomusic = XiaoMusic(config) - HttpInit(xiaomusic) - LOGGING_CONFIG = { "version": 1, "disable_existing_loggers": False, @@ -133,12 +133,61 @@ def main(): }, }, } - uvicorn.run( - HttpApp, - host=["::", "0.0.0.0"], - port=config.port, - log_config=LOGGING_CONFIG, - ) + + try: + filename = config.getsettingfile() + with open(filename) as f: + data = json.loads(f.read()) + config.update_config(data) + except Exception as e: + print(f"Execption {e}") + + def run_gate(): + uvicorn.run( + "gate:app", + host="0.0.0.0", + port=config.port, + log_config=LOGGING_CONFIG, + workers=2, + ) + + def run_server(): + xiaomusic = XiaoMusic(config) + HttpInit(xiaomusic) + uvicorn.run( + HttpApp, + host="127.0.0.1", + port=config.port + 1, + log_config=LOGGING_CONFIG, + ) + + # thread = threading.Thread(target=run_server) + # thread.start() + # run_gate() + + command = [ + "uvicorn", + "xiaomusic.gate:app", + "--workers", + "4", + "--host", + "0.0.0.0", + "--port", + str(config.port), + ] + + # process = subprocess.Popen(command) + def signal_handler(sig, frame): + print("主进程收到退出信号,准备退出...") + # process.terminate() # 终止子进程 + # process.wait() # 等待子进程退出 + print("子进程已退出") + os._exit(0) # 退出主进程 + + # 捕获主进程的退出信号 + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + run_server() if __name__ == "__main__": diff --git a/xiaomusic/gate.py b/xiaomusic/gate.py new file mode 100644 index 0000000..bf487b0 --- /dev/null +++ b/xiaomusic/gate.py @@ -0,0 +1,79 @@ +import json +import logging +import os +from contextlib import asynccontextmanager + +import httpx +from fastapi import FastAPI, Request +from fastapi.responses import Response +from fastapi.staticfiles import StaticFiles +from starlette.background import BackgroundTask + +from xiaomusic import __version__ +from xiaomusic.config import Config + +config = Config() +logging.basicConfig(level=logging.INFO) +log = logging.getLogger(__name__) + + +@asynccontextmanager +async def app_lifespan(app): + global config + try: + filename = config.getsettingfile() + with open(filename) as f: + data = json.loads(f.read()) + config.update_config(data) + except Exception as e: + log.exception(f"Execption {e}") + yield + + +app = FastAPI( + lifespan=app_lifespan, + version=__version__, +) + + +def reset_gate(): + # 更新 music 链接 + app.router.routes = [route for route in app.router.routes if route.path != "/music"] + app.mount( + "/music", + StaticFiles(directory=config.music_path, follow_symlink=True), + name="music", + ) + + +folder = os.path.dirname(__file__) +app.mount("/static", StaticFiles(directory=f"{folder}/static"), name="static") +reset_gate() + + +@app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"]) +async def proxy(path: str, request: Request): + async with httpx.AsyncClient() as client: + port = config.port + 1 + url = f"http://127.0.0.1:{port}/{path}" + response = await client.request( + method=request.method, + url=url, + headers=request.headers, + params=request.query_params, + content=await request.body() if request.method in ["POST", "PUT"] else None, + ) + if path == "savesetting": + # 使用BackgroundTask在响应发送完毕后执行逻辑 + background_task = BackgroundTask(reset_gate) + return Response( + content=response.content, + status_code=response.status_code, + headers=dict(response.headers), + background=background_task, + ) + return Response( + content=response.content, + status_code=response.status_code, + headers=dict(response.headers), + )