پایدارسازی اتصال WebSocket و مدیریت مشکلات متداول

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

در برنامه‌های Real-Time با WebSocket، قطع اتصال (Disconnect) و نیاز به اتصال مجدد (Reconnection) یکی از چالش‌های مهم است. مدیریت مناسب این شرایط باعث تجربه کاربری بهتر و افزایش پایداری سیستم می‌شود.

دلایل رایج قطع اتصال

  • مشکلات شبکه یا کاهش پهنای باند
  • Timeout سرور یا کلاینت
  • حمله‌های شبکه یا قطع عمدی اتصال
  • بروز خطا در پردازش پیام‌ها در سرور یا کلاینت

روش‌های پایدارسازی اتصال

  • Heartbeat / Ping-Pong: ارسال پیام‌های دوره‌ای بین کلاینت و سرور برای بررسی سلامت اتصال.
  • Retry با Backoff: در صورت قطع اتصال، کلاینت با تأخیرهای افزایشی (Exponential Backoff) تلاش به اتصال مجدد می‌کند.
  • State Recovery: ذخیره وضعیت کلاینت و پیام‌های در صف برای بازیابی پس از اتصال مجدد.
  • Keep-Alive Timeout: محدود کردن زمان عدم فعالیت قبل از قطع اتصال برای جلوگیری از منابع بلااستفاده.

نمونه سرور FastAPI با Heartbeat

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
import asyncio

app = FastAPI()

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    try:
        while True:
            try:
                # Timeout برای دریافت پیام
                data = await asyncio.wait_for(websocket.receive_text(), timeout=30.0)
                await websocket.send_text(f"Server received: {data}")
            except asyncio.TimeoutError:
                # ارسال پیام heartbeat
                await websocket.send_text("ping")
    except WebSocketDisconnect:
        print("Client disconnected")

نمونه کلاینت پایتون با Reconnection و مدیریت Heartbeat

import asyncio
import websockets

uri = "ws://127.0.0.1:8000/ws"

async def websocket_client():
    backoff = 1
    while True:
        try:
            async with websockets.connect(uri) as websocket:
                print("Connected to server")
                backoff = 1  # Reset backoff after successful connection
                while True:
                    message = input("Enter your message: ")
                    await websocket.send(message)
                    response = await websocket.recv()
                    if response == "ping":
                        print("Heartbeat received")
                    else:
                        print(f"Server response: {response}")
        except (websockets.exceptions.ConnectionClosed, ConnectionRefusedError):
            print(f"Connection lost. Reconnecting in {backoff} seconds...")
            await asyncio.sleep(backoff)
            backoff = min(backoff * 2, 30)  # Exponential backoff

asyncio.run(websocket_client())

توضیح:

  • در سرور، با استفاده از Timeout و پیام‌های heartbeat سلامت اتصال بررسی می‌شود.
  • کلاینت در صورت قطع اتصال با روش Exponential Backoff تلاش به اتصال مجدد می‌کند.
  • این روش از فشار زیاد به سرور هنگام قطع اتصال‌های مکرر جلوگیری می‌کند.
  • حفظ state و بازیابی پیام‌های از دست رفته در اتصال مجدد، به پایداری سیستم کمک می‌کند.

ثبت دیدگاه


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

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


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