C.W.K.
Stream
Lesson 06 of 07 · published

Middleware

~12 min · library, middleware, rate-limit

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

Connect 시점 middleware

connect handler 가 middleware 자리: auth, 버전 체크, geo-block, rate-limit 등록. 유용한 payload 가진 ConnectionRefusedError(code, message) raise — Socket.IO 가 둘 다 클라의 connect_error event 에 노출.

Event 별 rate limit

Rate-limit decorator 짜서 필요한 event (chat send, file upload) 에 적용. read-only event 엔 skip. sid 로 keyed 한 window 저장; connection 별 timestamp 의 작은 deque 면 충분.

Code

Connect 의 auth middleware·python
@sio.event
async def connect(sid, environ, auth):
    token = (auth or {}).get('token')
    user = decode_jwt(token) if token else None
    if not user:
        raise socketio.exceptions.ConnectionRefusedError(
            'unauthorized',
            'token missing or invalid',
        )
    if user.get('disabled'):
        raise socketio.exceptions.ConnectionRefusedError(
            'forbidden',
            'account disabled',
        )
    await sio.save_session(sid, {'user': user})
Event 별 rate-limit decorator·python
from collections import defaultdict, deque
import time, functools

windows = defaultdict(deque)  # sid -> deque of timestamps

def rate_limit(per_second=20):
    def deco(fn):
        @functools.wraps(fn)
        async def wrapper(sid, *args, **kwargs):
            now = time.time()
            w = windows[sid]
            while w and now - w[0] > 1.0:
                w.popleft()
            if len(w) >= per_second:
                await sio.emit('error',
                    {'code': 'rate_limited', 'message': 'slow down'},
                    to=sid)
                return
            w.append(now)
            return await fn(sid, *args, **kwargs)
        return wrapper
    return deco

@sio.on('chat:message')
@rate_limit(per_second=20)
async def chat(sid, data):
    # ...
    pass

External links

Exercise

Auth middleware + chat 에 5 message/sec rate limit 추가. 나쁜 token 으로 connect: connect_error 봐. 좋은 token 으로 100 message tight loop: 초당 첫 5 만 성공, 나머지가 error event 받는지 확인.

Progress

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

댓글 0

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

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