""" 主应用入口 """ from fastapi import FastAPI, WebSocket from fastapi.middleware.cors import CORSMiddleware from config import settings from websocket_handler import WebSocketHandler app = FastAPI(title="Tolan Backend API") # 配置CORS app.add_middleware( CORSMiddleware, allow_origins=["*"], # 生产环境应该限制具体域名 allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/") async def root(): """健康检查""" return {"status": "ok", "message": "Tolan Backend API"} @app.websocket("/ws") async def websocket_endpoint(websocket: WebSocket): """WebSocket端点""" handler = WebSocketHandler(websocket) await handler.handle_connection() if __name__ == "__main__": import uvicorn import os import socket from pathlib import Path # 🔥 DNS预解析(减少首次连接延迟) print("🔧 预解析DNS...") try: socket.getaddrinfo('dashscope.aliyuncs.com', 443) print("✅ DNS预解析完成\n") except Exception as e: print(f"⚠️ DNS预解析失败(不影响正常使用): {e}\n") # 打印启动配置 print("="*50) print("Tolan 后端服务启动") print("="*50) print(f"主机: {settings.HOST}") print(f"端口: {settings.PORT}") # SSL证书路径配置 # 优先使用环境变量配置的证书路径(生产环境) ssl_keyfile = settings.SSL_KEYFILE ssl_certfile = settings.SSL_CERTFILE # 如果环境变量未配置,使用本地开发证书 if not ssl_keyfile or not ssl_certfile: ssl_dir = Path(__file__).parent.parent / "ssl" ssl_keyfile = str(ssl_dir / "key.pem") ssl_certfile = str(ssl_dir / "cert.pem") # 检查证书是否存在 if ssl_keyfile and ssl_certfile: if not os.path.exists(ssl_keyfile) or not os.path.exists(ssl_certfile): print(f"⚠️ SSL证书不存在") print(f" 证书: {ssl_certfile}") print(f" 私钥: {ssl_keyfile}") print(" 将以HTTP模式启动") ssl_keyfile = None ssl_certfile = None else: print(f"✅ 使用SSL证书:") print(f" 证书: {ssl_certfile}") print(f" 私钥: {ssl_keyfile}") # 显示访问地址 protocol = "https" if ssl_keyfile and ssl_certfile else "http" ws_protocol = "wss" if ssl_keyfile and ssl_certfile else "ws" print(f"\n访问地址:") print(f" HTTP: {protocol}://{settings.HOST}:{settings.PORT}") print(f" WebSocket: {ws_protocol}://{settings.HOST}:{settings.PORT}/ws") print("="*50 + "\n") uvicorn.run( "main:app", host=settings.host, port=settings.port, reload=True, ssl_keyfile=ssl_keyfile, ssl_certfile=ssl_certfile, )