FastAPI 서버개발, WebSocket을 이용한 실시간 통신 구현

FastAPI는 현대적인 웹 API를 쉽게 구축할 수 있도록 설계된 파이썬 웹 프레임워크입니다. RESTful API뿐만 아니라 WebSocket을 이용한 실시간 통신 기능을 지원하는데, 이를 통해 클라이언트와 서버 간의 양방향 통신이 가능해집니다. 이번 글에서는 FastAPI를 사용하여 WebSocket을 통한 실시간 통신을 구현하는 방법에 대해 자세히 알아보겠습니다.

1. FastAPI 개요

FastAPI는 고성능 웹 서버를 구축하는 데 매우 효율적이며, 다음과 같은 주요 기능을 제공합니다.

  • 비동기 프로그래밍 지원: 비동기 처리를 통해 더 많은 요청을 동시에 처리할 수 있습니다.
  • 자동 문서화: Swagger UI와 ReDoc을 통해 자동으로 API 문서를 생성합니다.
  • Python 타입 힌트 활용: 타입 힌트를 통해 코드의 가독성과 유지보수성을 높입니다.

2. WebSocket이란?

WebSocket은 클라이언트와 서버 간의 전이중(Full-Duplex) 통신을 가능하게 하는 프로토콜입니다. HTTP와는 다르게, WebSocket을 사용하면 클라이언트가 서버에 요청하지 않고도 서버로부터 실시간 업데이트를 받을 수 있습니다. 이로 인해 채팅 응용 프로그램, 실시간 데이터 피드 등과 같은 다양한 애플리케이션에 적합합니다.

3. FastAPI 설치하기

FastAPI를 사용하려면 먼저 FastAPI와 ASGI 서버(Uvicorn)를 설치해야 합니다. 다음 명령어를 사용하여 설치할 수 있습니다:

pip install fastapi uvicorn

4. FastAPI WebSocket 예제

이제 FastAPI를 사용하여 간단한 WebSocket 서버를 구현해 보겠습니다. 이 예제에서는 클라이언트가 서버에 연결하고 메시지를 주고받는 기본적인 기능을 구현하겠습니다.

4.1 기본 WebSocket 서버 만들기

from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponse

app = FastAPI()

html = """




    
    
    WebSocket Chat


    

WebSocket Chat


""" @app.get("/") async def get(): return HTMLResponse(html) @app.websocket("/ws") async def websocket_endpoint(websocket: WebSocket): await websocket.accept() while True: data = await websocket.receive_text() await websocket.send_text(f"메시지 수신: {data}")

4.2 코드 설명

위 코드는 FastAPI를 사용하여 WebSocket 서버를 구현한 것입니다.

  • FastAPI 모듈에서 FastAPIWebSocket를 가져옵니다.
  • html 변수에 클라이언트 측 HTML 코드를 저장합니다. 클라이언트는 이 HTML 코드를 통해 WebSocket 서버에 연결하고 메시지를 주고받을 수 있습니다.
  • get() 함수는 클라이언트의 GET 요청에 대해 HTML 페이지를 반환합니다.
  • websocket_endpoint() 함수는 WebSocket 요청을 처리합니다. 클라이언트가 연결할 때 await websocket.accept()로 연결을 승인하고, 이후 클라이언트로부터 메시지를 받으면 확인 메시지를 다시 전송합니다.

5. 웹소켓 서버 실행하기

서버 코드를 작성한 후, 다음 명령어로 FastAPI 서버를 실행합니다:

uvicorn main:app --reload

이 명령어에서 main은 Python 파일의 이름이고, app는 FastAPI 인스턴스입니다.

6. WebSocket 클라이언트 테스트하기

브라우저에서 http://localhost:8000를 방문하면 웹소켓 채팅 인터페이스가 나타납니다. 메시지를 입력한 후 “전송” 버튼을 누르면, 서버에서 수신한 메시지가 다시 클라이언트로 전송되고, 텍스트 영역에 표시됩니다.

7. WebSocket의 고급 기능 구현하기

이제 기본적인 WebSocket 구현에 대해 알아보았으므로, 다음 단계로는 여러 클라이언트가 동시에 연결하여 서로 메시지를 주고받을 수 있는 기능을 추가하겠습니다. 이를 위해 클라이언트 관리를 위한 리스트와 메시지 방송 기능을 구현하겠습니다.

7.1 여러 클라이언트를 위한 코드 수정

from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponse
from typing import List

app = FastAPI()
clients: List[WebSocket] = []

html = """




    
    
    WebSocket Chat


    

WebSocket Chat


""" @app.get("/") async def get(): return HTMLResponse(html) @app.websocket("/ws") async def websocket_endpoint(websocket: WebSocket): await websocket.accept() clients.append(websocket) try: while True: data = await websocket.receive_text() for client in clients: if client != websocket: # 현재 클라이언트를 제외하고 메시지 전송 await client.send_text(f"전달된 메시지: {data}") except Exception as e: print("클라이언트가 연결을 종료했습니다.", e) finally: clients.remove(websocket)

7.2 추가된 기능 설명

위 코드에서는 클라이언트를 관리하는 clients 리스트를 추가하여 현재 연결된 모든 클라이언트를 저장합니다. 메시지를 수신하면, 모든 클라이언트에게 그 메시지를 전송하여 서로 간의 채팅이 가능하도록 합니다. 다음은 코드의 주요 변경 사항입니다:

  • 클라이언트가 연결될 때 clients 리스트에 추가합니다.
  • 서버는 모든 클라이언트에게 수신한 메시지를 전송하고, 현재 클라이언트를 제외합니다.
  • 예외가 발생할 경우(예: 클라이언트 연결 종료) finally 블록에서 해당 클라이언트를 리스트에서 제거합니다.

8. 클라이언트 어플리케이션 만들기

지금까지의 설명을 통해 간단한 WebSocket 서버를 구현했습니다. 이제는 위의 예제를 바탕으로 프론트엔드와 백엔드를 통합한 클라이언트 어플리케이션을 만들어보겠습니다. React, Vue.js, 또는 Angular와 같은 프론트엔드 프레임워크를 사용할 수 있습니다.

8.1 React를 통한 WebSocket 클라이언트 구현하기

React를 사용하여 WebSocket 클라이언트를 만들어보겠습니다.

import React, { useState, useEffect } from 'react';

function App() {
    const [socket, setSocket] = useState(null);
    const [message, setMessage] = useState('');
    const [chat, setChat] = useState([]);

    useEffect(() => {
        const ws = new WebSocket('ws://localhost:8000/ws');
        ws.onmessage = (event) => {
            setChat((prevChat) => [...prevChat, event.data]);
        };
        setSocket(ws);

        return () => {
            ws.close();
        };
    }, []);

    const sendMessage = () => {
        if (socket) {
            socket.send(message);
            setMessage('');
        }
    };

    return (
        

WebSocket Chat


setMessage(e.target.value)} placeholder="메시지를 입력하세요..." />
); } export default App;

9. 결론

이번 포스트를 통해 FastAPI를 사용하여 WebSocket을 통한 실시간 통신을 구현하는 방법에 대해 알아보았습니다. FastAPI의 장점을 살리면서, 비동기 방식으로 클라이언트와 서버 간의 실시간 소통을 구현할 수 있었습니다. 이러한 기술은 다양한 응용 분야에 활용될 수 있으며, 실시간 데이터 처리와 자극적인 UX를 제공하는 데 기여할 것입니다.

10. 참고 자료