38강. FastAPI와 WebSocket 소개

0. 학습 목표
→ 소켓 경험을 FastAPI·WebSocket 구조로 잇고, 앞으로 만들 단일 백엔드의 큰 그림을 잡습니다.
0.1 이번 글에서 다룰 내용
이번 글은 개념 중심 강의입니다.
37강까지 Python socket 모듈로 채팅 서버를 직접 만들었습니다.
연결 수락·수신·송신·종료를 손으로 다루며 네트워크 통신의 내부 흐름을 익혔습니다.
이번 강의부터는 그 경험을 바탕으로 FastAPI와 WebSocket으로 같은 채팅을 다시 만듭니다.
단, "다시 만드는 것"이 이 파트의 진짜 목표가 아닙니다.
이번에 세우는 FastAPI 서버는 PySide6 데스크톱 앱과 웹 관리창이 함께 붙는 하나의 중심 백엔드가 됩니다.
이번 강의에서는 코드를 짜지 않습니다. 39강부터 코드를 작성하기 전에 세 가지를 먼저 잡습니다.
FastAPI와 WebSocket이 무엇인지, async/await가 왜 등장하는지,
그리고 이 서버가 최종적으로 어떤 모양이 되는지입니다.

| 구분 | 내용 |
| 이해할 것 | FastAPI·WebSocket·async/await의 역할과, 단일 백엔드라는 이 파트의 목표 |
| 정리할 것 | TCP 소켓 방식과 WebSocket 방식의 공통점·차이점, 기능별 통신 방식 선택 기준 |
| 확인할 것 | 39강부터 만들 서버가 최종 구조의 어디에 해당하는지 |
0.2 앞으로 만들 전체 구조
이번 파트의 최종 모습입니다. 39강부터 FastAPI 서버를 세우고, 43강에서 PySide6 앱을 붙이고, 45강에서 웹 관리창을 얹습니다.
fastapi-chat/
├── server/
│ └── app.py ← FastAPI 서버 (채팅·로그인·관리) — 39강~
└── desktop/
└── main.py ← PySide6 앱 (WebSocket 연결) — 43강~
| 강 | 내용 |
| 39~42 | FastAPI WebSocket 채팅 서버 구축 → 브라우저로 동작 검증 |
| 43 | PySide6 앱의 소켓 통신을 WebSocket으로 교체 |
| 44 | 앱 로그인 화면 + 서버 인증 처리 |
| 45 | 웹 관리창(/admin)에서 접속자·로그인 기록 확인 |
| 46 | 데이터 저장을 메모리에서 MySQL로 전환 |
브라우저를 먼저 클라이언트로 쓰는 이유가 있습니다.
WebSocket 서버가 제대로 도는지 가벼운 브라우저로 먼저 검증한 뒤,
그 서버에 PySide6 앱을 붙여야 디버깅이 훨씬 쉽습니다.
1. 핵심 개념 이해하기
→ FastAPI가 무엇인지, WebSocket이 HTTP와 어떻게 다른지 정리합니다.
1.1 FastAPI란?

FastAPI는 Python으로 웹 서버를 만드는 프레임워크입니다.
직접 소켓 서버를 만들 때는 소켓 생성·접속 수락·수신·송신·종료를 모두 손으로 짰습니다.
FastAPI는 그 과정을 정해진 형태로 작성하게 해 주고,
한 서버 안에서 웹 페이지 제공·데이터 처리·실시간 통신을 함께 다룰 수 있습니다.
from fastapi import FastAPI
app = FastAPI()
@app.get("/") # 브라우저에서 주소를 열면 여기가 응답한다
def home():
return {"message": "Hello FastAPI"}
서버를 실행할 때는 uvicorn을 사용합니다. python server.py로 직접 소켓 서버를 띄웠던 자리와 같은 역할입니다.
uvicorn app:app --reload
1.2 HTTP와 WebSocket의 차이

일반 HTTP 요청은 "한 번 묻고 한 번 답하면 끝나는" 구조입니다.
식당에서 주문서를 내고 음식을 받으면 거래가 끝나는 것과 같습니다.
채팅은 이 방식으로 구현하기 어렵습니다.
상대가 언제 메시지를 보낼지 모르는데, 매번 새로 요청을 보내야 한다면 비효율적입니다.
WebSocket은 전화 통화에 가깝습니다.
한 번 연결하면 끊지 않고, 양쪽이 아무 때나 말할 수 있습니다.
서버가 먼저 메시지를 보내는 것도 가능합니다. 이것이 지금까지 만든 TCP 소켓과 목적이 같은 이유입니다.
| 구분 | HTTP | WebSocket |
| 연결 방식 | 요청·응답 후 종료 | 연결 유지 (양방향) |
| 서버가 먼저 보내기 | 불가 | 가능 |
| 이 프로젝트 용도 | 로그인·웹 관리창 | 실시간 채팅 |
이번 프로젝트에서는 둘 다 씁니다. 실시간 채팅은 WebSocket, 로그인 처리와 웹 관리창은 HTTP입니다. FastAPI는 한 서버에서 이 둘을 함께 제공합니다.
2. 구조로 확인하기
→ TCP 소켓과 WebSocket의 코드 대응을 보고, async/await가 threading을 대신하는 방식을 이해합니다.
2.1 TCP 소켓 → WebSocket 코드 대응
직접 만든 소켓 코드와 FastAPI WebSocket 코드를 나란히 놓으면, 하는 일이 거의 같다는 것을 알 수 있습니다.
달라진 건 작성 방식입니다.
| 역할 | TCP 소켓 | FastAPI WebSocket |
| 연결 수락 | server_socket.accept() |
await websocket.accept() |
| 메시지 수신 | conn.recv(1024) |
await websocket.receive_text() |
| 메시지 송신 | conn.sendall(...) |
await websocket.send_text(...) |
| 여러 클라이언트 처리 | threading.Thread |
async def + await |
가장 작은 WebSocket 에코 서버는 다음과 같습니다. 지금은 흐름만 읽어 봅니다. 39강에서 직접 실행해 확인합니다.
from fastapi import FastAPI, WebSocket
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept() # 연결 수락 — accept()와 같은 역할
while True:
message = await websocket.receive_text() # 메시지 도착까지 대기 — recv()와 비슷
await websocket.send_text(f"서버 응답: {message}")
2.2 async/await는 왜 등장하는가?

직접 소켓 서버를 만들 때 threading.Thread를 썼습니다.
클라이언트마다 스레드를 하나씩 만들어서 동시에 여러 명을 처리한 방식이었습니다.
WebSocket 서버에서는 async def와 await로 같은 문제를 풉니다.
await는 "이 작업이 끝날 때까지 기다리는 동안 다른 작업을 처리해도 된다"는 신호입니다.
recv()가 메시지를 기다리는 시간에 다른 클라이언트의 메시지를 처리할 수 있습니다.
스레드를 여러 개 만들지 않고도 동시에 여러 연결을 다룰 수 있는 이유입니다.
| 구분 | threading | async/await |
| 동시 처리 방식 | 클라이언트마다 스레드 생성 | 대기 시간을 다른 작업에 활용 |
| 코드 흐름 | 함수 정의 그대로 | async def, await 키워드 필요 |
| FastAPI에서 | 일반적으로 사용하지 않음 | WebSocket 함수의 기본 방식 |
지금은 "기다리는 작업 앞에 await를 붙인다"는 것만 이해하면 됩니다.
실제로 코드를 작성하면서 익히는 것이 훨씬 빠릅니다.
3. 판단 기준 정리하기
→ 소켓 방식에서 FastAPI로 넘어오는 이유와, 기능별 통신 방식 선택 기준을 정리합니다.
3.1 소켓으로 먼저 배운 이유, 지금 FastAPI로 바꾸는 이유

37강까지 소켓을 직접 만든 이유는 네트워크 통신의 내부 흐름을 몸으로 이해하기 위해서였습니다.
연결·수신·송신·종료를 직접 다뤄 봤기 때문에, 이제 FastAPI가 그 역할을 어떻게 대신해 주는지 비교하며 이해할 수 있습니다. 기초를 건너뛰고 FastAPI부터 배웠다면 "이게 안에서 뭘 하는지" 모른 채 쓰게 됩니다.
FastAPI로 바꾸는 이유는 이번 파트의 최종 목표 때문입니다.
직접 만든 소켓 서버는 채팅 하나만 처리합니다. 로그인 API나 웹 관리창을 붙이려면 별도 서버가 필요해집니다.
FastAPI는 WebSocket 채팅·로그인 API·HTML 관리 페이지를 한 서버에서 모두 제공할 수 있어서, 데스크톱 앱과 웹이 하나의 백엔드를 공유하는 구조를 만들기에 적합합니다.
3.2 기능별 통신 방식 선택 기준
하나의 FastAPI 서버 안에서도 기능마다 어울리는 통신 방식이 다릅니다.
기준은 단순합니다. 연결을 유지하며 서버가 먼저 말을 걸어야 하면 WebSocket, 한 번 요청하고 끝나면 HTTP입니다.
| 기능 | 통신 방식 | 이유 |
| 실시간 채팅 | WebSocket | 연결 유지, 서버가 먼저 보냄 |
| 로그인 | HTTP | 한 번 보내고 응답받으면 끝 |
| 웹 관리창 | HTTP | 브라우저에서 페이지 요청 |
✔ 확인 기준: "실시간 채팅은 WebSocket, 로그인·관리 페이지는 HTTP이며, 하나의 FastAPI 서버가 둘을 함께 제공한다"를 말할 수 있으면 완료. WebSocket도 처음 연결할 때는 HTTP 핸드셰이크를 거친다는 것을 알고 있으면 충분합니다.
→ 다음 강의 (39강): FastAPI WebSocket으로 가장 기본적인 채팅 서버를 만듭니다. 연결 수락 → 접속자 목록 관리 → 브로드캐스트 → 연결 종료까지, 이번 강의에서 대응표로 본 소켓 구조를 코드로 직접 확인합니다. 이 서버가 43강에서 PySide6 앱이 붙고 45강에서 웹 관리창이 얹히는 중심 서버입니다.