웹소켓 적용중

This commit is contained in:
2026-02-24 23:20:42 +09:00
parent 153b1bed17
commit fc8c30b7e1
6 changed files with 467 additions and 116 deletions

View File

@@ -18,6 +18,7 @@ import pytz
from app.core.config import settings
from app.api import api_router
from app.services.websocket_manager import websocket_manager
from app.core.json_helpers import _dumps
from app.services.db_worker import db_writer_worker
from app.core.database import engine, Base, AsyncSessionLocal
from app.models import models # 모델 임포트
@@ -459,6 +460,8 @@ async def websocket_endpoint(websocket: WebSocket, client_id: str):
{"type": "subscribe", "stock_codes": [...]} → ACK
{"type": "unsubscribe", "stock_codes": [...]} → ACK
{"type": "set_subscriptions", "stock_codes": [...]} → ACK
{"type": "get_chart", "stock_code": "...", "period": "D", "limit": 200}
→ {"type": "chart_data", ...}
그 외 메시지 → echo
"""
await websocket_manager.connect(websocket, client_id)
@@ -516,6 +519,44 @@ async def websocket_endpoint(websocket: WebSocket, client_id: str):
}),
client_id,
)
# 구독 종목 차트 캐시 사전 워밍업 (백그라운드, 논블로킹)
# 사용자가 종목 클릭 전에 캐시가 완성되도록 미리 KIS API 호출
if codes:
async def _warmup_chart_cache(stock_codes: list):
from app.api.endpoints.market_data import get_chart_data_cached, chart_cache
from datetime import datetime
for code in stock_codes:
# 이미 유효한 캐시가 있으면 건너뜀
cached = chart_cache.get(f"{code}__D")
if cached and (datetime.now() - cached["timestamp"]).total_seconds() < 600:
continue
try:
await get_chart_data_cached(code, "D", 100)
logger.debug(f"[warmup] {code} 차트 캐시 완료")
except Exception as e:
logger.debug(f"[warmup] {code} 캐시 실패: {e}")
asyncio.create_task(_warmup_chart_cache(codes))
continue
if msg_type == "get_chart":
stock_code = str(msg.get("stock_code", "")).strip()
period = msg.get("period", "D")
limit = int(msg.get("limit", 200))
if not stock_code:
continue
try:
from app.api.endpoints.market_data import get_chart_data_cached
chart_data = await get_chart_data_cached(stock_code, period, limit)
await websocket_manager.send_personal_message(
_dumps({"type": "chart_data", "stock_code": stock_code, "period": period, "data": chart_data}),
client_id,
)
except Exception as e:
logger.error(f"get_chart 오류 ({stock_code}): {e}")
await websocket_manager.send_personal_message(
_dumps({"type": "chart_data", "stock_code": stock_code, "period": period, "data": [], "error": str(e)}),
client_id,
)
continue
await websocket_manager.send_personal_message(f"Echo: {data}", client_id)