결과화면

console에 보다시피, 메시지를 계속 받아와 화면에 뿌려지고 있다.
1. wscat 설치
npm install -g wscat
2-1.FastAPI , app.py ( 방법 1)


1) 필요한 라이브러리들 Import
- FastAPI/WebSocket → 웹소켓 서버 만들 때 필요
- websockets → FastAPI 내부에서 Upbit WebSocket과 연결할 때 필요
- json → 구독 메시지를 JSON 문자열로 바꿀 때 사용
- chart_router → 기존 REST API 라우터(chart/candle) 등록
2) CORS 설정
React 프론트엔드(3000포트)가 API를 호출할 때 CORS 오류가 생기지 않도록 허용.
3) 업비트 웹소켓 주소
FastAPI가 대신 Upbit WebSocket에 연결해서 데이터를 가져온 다음 React로 전달해 준다.
★ 4) 핵심: FastAPI → Upbit → React 로 중계(WebSocket Proxy)
@app.websocket("/ws/ticker")
async def ticker(ws: WebSocket):
클라이언트(React)가 접속하는 WebSocket URL
React는 ws://백엔드주소/ws/ticker 로 접속한다.
await ws.accept()
React(클라이언트)의 연결을 수락
async with websockets.connect(UPBIT_WS_URL) as upbit_ws:
FastAPI 서버가 업비트 웹소켓과 연결
서버는 React와 동시에 업비트와도 연결이 된다. 즉, FastAPI 중계(proxy) 서버가 된다.
subscribe = [
{"ticket": "proxy"},
{"type": "ticker", "codes": ["KRW-BTC"]},
]
await upbit_ws.send(json.dumps(subscribe))
업비트에게 "나 BTC 티커 데이터 보고싶어." 라고 구독 메시지를 보낸다.
while True:
data = await upbit_ws.recv()
await ws.send_text(data)
- 업비트 → FastAPI 서버로 실시간 데이터 수신
- FastAPI → React로 즉시 전달
즉, FastAPI는 중간에서 데이터만 전달하는 역할을 한다.
from fastapi.middleware.cors import CORSMiddleware
from fastapi import FastAPI, WebSocket
from controller.chart import router as chart_router
import websockets
import json
app = FastAPI()
app.include_router(chart_router)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
UPBIT_WS_URL = "wss://api.upbit.com/websocket/v1"
# ------------------------------
# WebSocket은 반드시 app.py에
# ------------------------------
@app.websocket("/ws/ticker")
async def ticker(ws: WebSocket):
await ws.accept()
async with websockets.connect(UPBIT_WS_URL) as upbit_ws:
subscribe = [
{"ticket": "proxy"},
{"type": "ticker", "codes": ["KRW-BTC"]},
]
await upbit_ws.send(json.dumps(subscribe))
while True:
data = await upbit_ws.recv()
await ws.send_text(data)
{"ticket": "proxy"} — proxy는 아무 문자열이나 가능함
- 보통 프로그램이름, 클라이언트 ID, 브라우저 구분 등으로 넣는다.
ex )
{"ticket": "react-dashboard"}
{"ticket": "fastapi-server"}
{"ticket": "client-01"}
{"type": "ticker"} — 이건 반드시 정해진 값 중 하나여야 함
1. ticker - 현재 시세 정보
2. trade - 체결 정보
3. orderbook - 호가 정보
2-1.FastAPI , ws > ticker_ws.py ( 방법 2)

from fastapi import APIRouter, WebSocket
import websockets
import json
router = APIRouter()
UPBIT_WS_URL = "wss://api.upbit.com/websocket/v1"
@router.websocket("/ws/ticker")
async def ticker(ws: WebSocket):
await ws.accept()
async with websockets.connect(UPBIT_WS_URL) as upbit_ws:
subscribe = [
{"ticket": "proxy"},
{"type": "ticker", "codes": ["KRW-BTC"]},
]
await upbit_ws.send(json.dumps(subscribe))
while True:
data = await upbit_ws.recv()
await ws.send_text(data)
app.py

이렇게 관리하게 되면 , app.py에 WebSocket을 때려 박는 것보다 훨씬 유지보수가 쉽고 간편하게 된다.

3. React

1) FastAPI WebSocket 서버에 연결
useEffect(() => {
const ws = new WebSocket("ws://127.0.0.1:8000/ws/ticker");
FastAPI의 /ws/ticker와 연결됨 → 조회할 때 바로 실시간 데이터 들어옴.
2) 메시지를 받을 때 실행되는 코드
ws.onmessage = async (event) => {
const text = await event.data.text(); // Blob → text 변환
const json = JSON.parse(text); // JSON 변환
console.log("Ticker:", json);
setData(json); // 화면 업데이트
};
여기서 중요한 포인트
- FastAPI가 보내는 데이터는 Blob 타입으로 오기 때문에
→ text()로 변환해야 JSON.parse 가능 - 변환 후 React 화면에 보여주기 위해 setData(json) 저장
3) 컴포넌트 종료 시 WebSocket 닫기
return () => ws.close();
안 닫으면 메모리 누수 발생.
import { useEffect, useState } from "react";
function Wbsocket() {
const [data, setData] = useState(null);
useEffect(() => {
const ws = new WebSocket("ws://127.0.0.1:8000/ws/ticker");
ws.onmessage = async (event) => {
const text = await event.data.text(); // 🔥 Blob → text 변환
const json = JSON.parse(text); // 이제 JSON.parse 가능
console.log("Ticker:", json);
setData(json); // 🔥 화면 업데이트
};
return () => ws.close();
}, []);
return (
<div>
<h1>WebSocket Data</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
}
export default Wbsocket;
Upbit WS → FastAPI 서버 → React WebSocket
< 전체 동작 요약 >
- React가 ws://localhost:8000/ws/ticker로 접속
- FastAPI는 React 접속을 수락
- FastAPI는 업비트 WebSocket에도 동시에 연결
- FastAPI가 업비트에 ticker 구독 요청
- 업비트 → FastAPI로 실시간 데이터 전송
- FastAPI → React로 그대로 재전송(proxy)
- React에서 Blob → text → JSON 변환
- 실시간으로 화면 업데이트
'✨ python > FastAPI' 카테고리의 다른 글
| [FastAPI, Recat] 이전 데이터 + 실시간 데이터(WebSocket) 합하기 (2) (0) | 2025.12.12 |
|---|---|
| [FastAPI, Recat] 이전 데이터 + 실시간 데이터(WebSocket) 합하기 (1) (0) | 2025.12.12 |
| FastAPI로 업비트 차트 React로 JSON 형식 데이터 가져오기 (0) | 2025.12.08 |
| 업비트 API 환경변수 세팅 및 FastAPI 로 자산 조회하기 (0) | 2025.12.06 |
| VisualStudio로 FastAPI와 React 쉽게 연동하기 (0) | 2025.12.06 |
댓글