مدیریت ترافیک و محدود کردن نرخ پیام‌ها در WebSocket

  • مدرس : علی بیگدلی
  • تاریخ انتشار: 1404/06/25
  • تعداد بازدید: 2

در برنامه‌های Real-Time با WebSocket، حجم زیادی از پیام‌ها می‌تواند باعث مصرف زیاد منابع سرور و پهنای باند شود. برای جلوگیری از مشکلات ناشی از ترافیک زیاد و حفظ کیفیت سرویس، می‌توان نرخ پیام‌ها (Rate Limiting) را مدیریت کرد.

مزایای محدود کردن نرخ پیام‌ها

  • حفاظت از سرور در برابر حملات DoS یا استفاده بیش از حد
  • کاهش مصرف پهنای باند و منابع شبکه
  • بهبود تجربه کاربری با جلوگیری از تأخیر زیاد یا قطع اتصال
  • امکان اعمال سیاست‌های عادلانه برای کاربران متعدد

روش‌های مدیریت ترافیک

  • Token Bucket: هر کاربر یک «سطل» از توکن‌ها دارد که به مرور پر می‌شود. ارسال هر پیام یک توکن مصرف می‌کند و اگر سطل خالی باشد پیام رد یا تأخیر داده می‌شود.
  • Leaky Bucket: پیام‌ها با نرخ ثابت ارسال می‌شوند و اگر بیش از ظرفیت برسد، اضافی‌ها رها یا صف‌بندی می‌شوند.
  • Sliding Window: تعداد پیام‌های ارسال شده در یک بازه زمانی مشخص محدود می‌شود.

نمونه پیاده‌سازی ساده Rate Limiting در FastAPI

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
import asyncio
from collections import defaultdict
from datetime import datetime, timedelta

app = FastAPI()

# ذخیره‌سازی زمان آخرین پیام‌ها برای هر کلاینت
last_message_time = defaultdict(lambda: datetime.min)
MESSAGE_INTERVAL = timedelta(seconds=1)  # حداقل فاصله بین پیام‌ها

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    client_id = id(websocket)
    try:
        while True:
            data = await websocket.receive_text()
            now = datetime.utcnow()
            if now - last_message_time[client_id] < MESSAGE_INTERVAL:
                await websocket.send_text("Rate limit exceeded. Please wait.")
                continue
            last_message_time[client_id] = now
            await websocket.send_text(f"Server received: {data}")
    except WebSocketDisconnect:
        print("Client disconnected")

نمونه کلاینت پایتون

import asyncio
import websockets

async def websocket_client():
    uri = "ws://127.0.0.1:8000/ws"
    async with websockets.connect(uri) as websocket:
        while True:
            message = input("Enter your message: ")
            await websocket.send(message)
            response = await websocket.recv()
            print(f"Server response: {response}")

asyncio.run(websocket_client())

توضیح:

  • در این مثال، حداقل فاصله بین پیام‌ها یک ثانیه است.
  • اگر کلاینت سریع‌تر از این فاصله پیام ارسال کند، پیام سرور با هشدار Rate limit exceeded پاسخ داده می‌شود.
  • روش‌های پیچیده‌تر مانند Token Bucket و Sliding Window برای سیستم‌های با تعداد کاربر زیاد و بار بالا مناسب هستند.
  • مدیریت نرخ پیام‌ها باعث افزایش پایداری و امنیت سیستم WebSocket می‌شود.

ثبت دیدگاه


نکته: آدرس ایمیل شما منتشر نخواهد شد

دیدگاه کاربران (0)


هیچ دیدگاهی ثبت نشده است. می‌توانید اولین نفر باشید.