본문 바로가기
C.W.K.
Stream
Lesson 03 of 08 · published

에코 서버

~10 min · fastapi, echo, html-test-page

Level 0Poller
0 XP0/60 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

완전한 루프백 서버

앞의 두 레슨을 하나로 묶어 보자. 모든 메시지를 시각, 서버 이름, 종류가 들어 있는 작은 봉투로 감싸 돌려주고, 같은 FastAPI 앱의 / 경로에서 작은 HTML 시험 페이지도 제공하는 에코 서버야. 애플리케이션 로직을 만드는 동안 기본 동작을 빠르게 확인하는 실험장으로 유용해.

HTML 페이지를 함께 두는 이유

브라우저는 https:// 페이지에서 ws:// 연결을 거절하고, 많은 사내 프록시는 가공하지 않은 ws:// 자체를 막아. 시험용 클라이언트를 같은 출처에서 제공하면 두 문제를 모두 피할 수 있어. cwkPippa 도 비슷해. 개발 중에는 React UI 와 FastAPI 백엔드를 이웃한 포트에서 띄우고, 운영 배포에서는 한 출처 뒤에 둬.

Code

한 파일에 담은 에코 서버와 시험 페이지·python
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
from datetime import datetime

app = FastAPI()

@app.websocket('/ws')
async def echo(websocket: WebSocket):
    await websocket.accept()
    await websocket.send_json({
        'type': 'system',
        'message': 'connected to echo',
        'ts': datetime.now().isoformat(),
    })
    try:
        async for msg in websocket.iter_json():
            await websocket.send_json({
                'type': 'echo',
                'original': msg,
                'ts': datetime.now().isoformat(),
                'server': 'fastapi-echo-v1',
            })
    except WebSocketDisconnect:
        # Client closed; nothing to clean up here yet.
        pass

@app.get('/')
async def index():
    return HTMLResponse('''
<!doctype html><html><body>
<input id=msg placeholder="type and Enter">
<pre id=log></pre>
<script>
  const log = document.getElementById('log');
  const ws = new WebSocket('ws://' + location.host + '/ws');
  ws.onmessage = e => log.textContent += e.data + '\n';
  document.getElementById('msg').addEventListener('keydown', e => {
    if (e.key === 'Enter') {
      ws.send(JSON.stringify({ text: e.target.value }));
      e.target.value = '';
    }
  });
</script>
</body></html>''')

External links

Exercise

한 파일로 만든 에코 서버를 띄우고 브라우저에서 http://localhost:8000/ 을 열어. 메시지 다섯 개를 보내 로그에서 봉투 구조를 확인해. 탭을 닫아 연결을 끊었다가 다시 연결하고, 서버가 traceback 없이 WebSocketDisconnect 를 깔끔하게 기록하는지 확인해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.