microdot.websocket — תמיכת WebSocket

WebSockets הם חיבור דו-כיווני מתמשך מעל HTTP – לאחר לחיצת יד של שדרוג, הלקוח והשרת שולחים ומקבלים הודעות ממוסגרות על אותו socket. השתמשו בהם כאשר המצלמה ויישום בצד הדפדפן זקוקים לתעבורה דו-כיוונית מלאה (full-duplex) ש-SSE (דחיפה חד-כיוונית) וקריאת HTTP פשוטה (polling) אינם יכולים לספק בזול.

class WebSocket

class microdot.websocket.WebSocket(request)

ה-handle שהנתיב מקבל. מועבר למטפלים כארגומנט השני כאשר with_websocket() בשימוש; אין לבנות אותו ישירות.

מאפייני מחלקה

max_message_length: int

גודל ה-payload המרבי ש-receive() יקבל. הודעות גדולות מכך מעלות WebSocketError וסוגרות את החיבור. 0 משבית את הבדיקה (היו מודעים להתקפות מיצוי-זיכרון אם תגדירו זאת). -1 (ברירת מחדל) משתמש ב-Request.max_body_length.

CONT: int

Opcode של פריים-המשך, 0x0. מסמן פריים שממשיך את ה-payload של הפריים הקודם עבור אותה הודעה. Microdot עצמו אינו מייצר פריימי-המשך (כל הודעה יוצאת כפריים בודד) ודוחה אותם בקבלה, אך הקבוע נחשף עבור יישומים שמממשים מסגור מותאם אישית.

TEXT: int

Opcode של פריים-טקסט, 0x1. ה-opcode ש-send() בוחר אוטומטית כאשר data הוא str; ה-payload מקודד ב-UTF-8 ביציאה.

BINARY: int

Opcode של פריים-בינארי, 0x2. ה-opcode ש-send() בוחר אוטומטית כאשר data הוא bytes / bytearray; ה-payload נשלח כפי שהוא.

CLOSE: int

Opcode של פריים-סגירה, 0x8. נשלח על ידי close(); קבלת אחד כזה מעלה WebSocketError (”Websocket connection closed“) מתוך receive().

PING: int

Opcode של פריים-ping, 0x9. Microdot עונה אוטומטית ל-pings נכנסים עם PONG תואם בתוך receive(); היישום בדרך כלל אינו מבחין בהם.

PONG: int

Opcode של פריים-pong, 0xA. נשלח אוטומטית כתשובה ל-PING. pongs נכנסים נזרקים בשקט.

מאפייני מופע

request: microdot.Request

ה-microdot.Request שמקורו בו – אותו אובייקט שמטפל הנתיב קיבל.

closed: bool

True ברגע ש-close() הורץ. בדקו זאת כדי להימנע מסגירה כפולה בנתיבי ניקוי.

מתודות

async receive()

המתינו והחזירו את ההודעה הבאה מהלקוח. סוג ההחזרה תואם ל-opcode של הפריים: str לפריימי טקסט, bytes לפריימים בינאריים. פריימי ping נענים אוטומטית עם pong; פריימי pong נזרקים בשקט; פריים close מעלה WebSocketError (”Websocket connection closed“).

async send(data, opcode: int | None = None)

שלחו data ללקוח. מחרוזות נשלחות כפריימי טקסט, בתים כפריימים בינאריים; העבירו opcode במפורש כדי לעקוף.

async close()

שלחו פריים סגירה וסמנו את החיבור כסגור. נקראת אוטומטית כאשר העטיפה של with_websocket() יוצאת.

class WebSocketError

exception microdot.websocket.WebSocketError

מועלה בתוך WebSocket.receive() כאשר החיבור מסתיים או שהפרוטוקול מופר. השתמשו בזה בתוך נתיב כדי לזהות ניתוקי לקוח רגילים:

try:
    message = await ws.receive()
except WebSocketError:
    # client closed the connection

מעטרים ברמת המודול

microdot.websocket.with_websocket(f)

מעטר (decorator) שהופך נתיב לנקודת קצה של WebSocket. המטפל מקבל את הבקשה ואובייקט WebSocket

from microdot import Microdot
from microdot.websocket import with_websocket

app = Microdot()

@app.get('/echo')
@with_websocket
async def echo(request, ws):
    while True:
        msg = await ws.receive()
        await ws.send(msg)

אורך חיי המטפל שווה לאורך חיי החיבור. החזרה, העלאת חריגה, או ניתוק לקוח סוגרים את ה-WebSocket באופן נקי.

async microdot.websocket.websocket_upgrade(request)

פונקציית עזר לשדרוג ברמה נמוכה. השתמשו בזה בתוך נתיב כאשר השדרוג צריך להתרחש באופן מותנה – למשל רק לאחר שבדיקת הרשאה עוברת:

@app.get('/private')
async def private(request):
    if not authenticate(request):
        abort(401)
    ws = await websocket_upgrade(request)
    while True:
        msg = await ws.receive()
        await ws.send(msg.upper())

מחזיר את ה-WebSocket המשודרג. המטפל חייב להחזיר microdot.Response.already_handled (או להעלות חריגה) ברגע שסיים – microdot כבר השתלט על ה-socket.

המימוש תומך ב-opcodes הסטנדרטיים של טקסט ובינארי, ping / pong, וסגירה נקייה. פריימים מקוטעים (המשך) אינם נתמכים – כל הודעה נשלחת כפריים בודד, מה שמתאים ליישומי מצלמה טיפוסיים עם הודעות קטנות.