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

실시간 채팅 시스템

~13 min · app, chat, rooms, presence

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

채팅 백엔드 해부하기

실전 채팅 시스템은 작고 경계가 분명한 조각의 합이야. 트랙 4 의 방과 트랙 4 의 연결 신원, 트랙 5 의 봉투형 메시지 프로토콜에 DB 영속화, 입력 중 표시, 읽음 확인, 연결 시 대화 기록 가져오기를 더하지. 하나씩 보면 어렵지 않고, 핵심은 조합 가능한 상태를 유지하는 거야.

영속화는 REST, 실시간 전달은 밀어 주기

운영에서 흔한 방식은 채팅 메시지를 REST 엔드포인트로 POST 하고 DB 에 저장한 뒤 WebSocket 으로 펼치는 거야. WebSocket 은 현재 연결에 전달하고 DB 는 대화 기록을 책임져. 다시 연결한 클라이언트는 REST GET /messages?since=... 로 놓친 기록을 가져온 뒤 WebSocket 으로 새 메시지를 받아. 경로는 둘이지만 진실의 원천은 하나야.

Code

서버: 영속화와 전체 전송을 갖춘 채팅 처리기·python
from datetime import datetime
import uuid

class ChatServer:
    def __init__(self, manager, db):
        self.manager = manager
        self.db = db

    async def on_message(self, ws, user, msg):
        t = msg.get('type')
        data = msg.get('data', {})

        if t == 'chat.send':
            saved = {
                'id': str(uuid.uuid4()),
                'room': data['room'],
                'text': data['text'],
                'from': user['id'],
                'ts': datetime.utcnow().isoformat() + 'Z',
            }
            await self.db.messages.insert(saved)
            await self.manager.broadcast(data['room'], {
                'type': 'chat.message',
                'data': saved,
            })

        elif t == 'chat.typing':
            await self.manager.broadcast(data['room'], {
                'type': 'chat.typing',
                'data': {'user': user['id'], 'is_typing': data['is_typing']},
            }, exclude=ws)

        elif t == 'chat.read':
            await self.manager.send_to_user(data['target_user'], {
                'type': 'chat.read_receipt',
                'data': {
                    'reader': user['id'],
                    'message_id': data['message_id'],
                },
            })

        elif t == 'chat.history':
            history = await self.db.messages.last_n(data['room'], 50)
            await ws.send_json({'type': 'chat.history', 'data': history})

External links

Exercise

SQLite 영속화를 갖춘 위 채팅 서버를 만들어. 같은 방에 서로 다른 사용자로 브라우저 탭 두 개를 열고 메시지, 입력 중 표시, 읽음 확인을 보내. 서버를 다시 시작하고 재연결해 기록을 가져와 메시지가 남아 있는지 확인해. 입력 중 표시는 입력한 사용자에게 되돌아오지 않아야 해.

Progress

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

댓글 0

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

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