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

여러 연결에 메시지 보내기

~12 min · fastapi, broadcast, exclude, background-task

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

전체 전송의 세 가지 형태

실전에서는 세 형태를 자주 써. 방 전체 전송 은 방에 있는 모두에게 보내고, 발신자를 뺀 방 전체 전송 은 보낸 사용자에게 같은 메시지가 되돌아가는 것을 막아. 특정 사용자에게 직접 보내기 까지 하려면 user_id → WebSocket 관계도 추적해야 해. 관리자에 셋을 모두 구현하면 대부분의 요구를 다룰 수 있어.

서버가 먼저 보내기

가격 시세, 시스템 지표, 심박 전체 전송처럼 주기적인 갱신에는 lifespan 시작 단계에서 백그라운드 작업을 띄워. manager.broadcast() 를 부르는 이 작업은 특정 클라이언트 요청과 무관하게 애플리케이션이 살아 있는 동안 계속 돌아가.

Code

발신자 제외와 사용자 직접 전송·python
class ConnectionManager:
    # ... rooms as before ...
    user_map: Dict[str, WebSocket] = {}

    async def broadcast(self, room: str, message: dict, *, exclude: WebSocket | None = None):
        dead = []
        for ws in self.rooms.get(room, set()):
            if ws is exclude:
                continue
            try:
                await ws.send_json(message)
            except Exception:
                dead.append(ws)
        for ws in dead:
            self.disconnect(ws, room)

    async def send_to_user(self, user_id: str, message: dict):
        ws = self.user_map.get(user_id)
        if ws is None:
            return False
        try:
            await ws.send_json(message)
            return True
        except Exception:
            self.user_map.pop(user_id, None)
            return False
lifespan 으로 백그라운드 시세 전송하기·python
from contextlib import asynccontextmanager
import asyncio
from fastapi import FastAPI

@asynccontextmanager
async def lifespan(app: FastAPI):
    task = asyncio.create_task(price_ticker())
    yield
    task.cancel()

async def price_ticker():
    while True:
        price = await get_latest_btc()
        await manager.broadcast('btc-feed', {
            'type': 'price.update',
            'data': {'symbol': 'BTC', 'price': price},
        })
        await asyncio.sleep(1)

app = FastAPI(lifespan=lifespan)

External links

Exercise

연결 관리자에 send_to_userbroadcast(..., exclude=...) 를 추가해. 채팅 엔드포인트에서 모든 메시지를 발신자를 뺀 방 전체에 보내고, 발신자에게만 chat.ack 를 직접 보내. 브라우저 탭 세 개를 열어 발신자만 ack 를 보고 나머지 둘은 chat.message 를 보는지 확인해.

Progress

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

댓글 0

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

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