microdot.websocket --- รองรับ WebSocket

WebSocket เป็นการเชื่อมต่อแบบสองทิศทางถาวรผ่าน HTTP -- หลังจากกระบวนการ upgrade handshake เสร็จสิ้น ทั้งฝั่ง client และ server จะสามารถส่งและรับข้อความในรูปแบบ frame บน socket เดียวกัน ใช้งานเมื่อกล้องและแอปพลิเคชันฝั่งเบราว์เซอร์ต้องการการสื่อสารแบบ full-duplex ซึ่ง SSE (การส่งข้อมูลทางเดียว) และการ polling แบบ HTTP ธรรมดาไม่สามารถรองรับได้อย่างมีประสิทธิภาพ

class WebSocket

class microdot.websocket.WebSocket(request)

handle ที่ route ได้รับ ส่งไปยัง handler เป็นอาร์กิวเมนต์ที่สองเมื่อใช้งาน with_websocket() อย่าสร้างออบเจกต์นี้โดยตรง

Class attributes

max_message_length: int

ขนาด payload สูงสุดที่ receive() จะยอมรับ ข้อความที่มีขนาดเกินกว่านี้จะ raise WebSocketError และปิดการเชื่อมต่อ 0 ปิดการตรวจสอบ (ระวังการโจมตีแบบหมดหน่วยความจำหากตั้งค่านี้) -1 (ค่าเริ่มต้น) ใช้ค่าจาก Request.max_body_length

CONT: int

Continuation-frame opcode คือ 0x0 ทำเครื่องหมาย frame ที่ต่อเนื่อง payload จาก frame ก่อนหน้าสำหรับข้อความเดียวกัน Microdot ไม่สร้าง continuation frame เอง (แต่ละข้อความส่งออกเป็น frame เดียว) และปฏิเสธ continuation frame ที่รับเข้ามา แต่ค่าคงที่นี้เปิดให้แอปพลิเคชันที่ใช้ custom framing เข้าถึงได้

TEXT: int

Text-frame opcode คือ 0x1 เป็น opcode ที่ send() เลือกโดยอัตโนมัติเมื่อ data เป็น str โดย payload จะถูกเข้ารหัสแบบ UTF-8 ในขณะส่งออก

BINARY: int

Binary-frame opcode คือ 0x2 เป็น opcode ที่ send() เลือกโดยอัตโนมัติเมื่อ data เป็น bytes / bytearray โดย payload จะถูกส่งออกตามที่เป็น

CLOSE: int

Close-frame opcode คือ 0x8 ส่งโดย close() เมื่อรับ opcode นี้จะ raise WebSocketError ("Websocket connection closed") จาก receive()

PING: int

Ping-frame opcode คือ 0x9 Microdot จะตอบ ping ที่เข้ามาด้วย PONG ที่ตรงกันโดยอัตโนมัติภายใน receive() โดยปกติแอปพลิเคชันไม่จำเป็นต้องรับรู้

PONG: int

Pong-frame opcode คือ 0xA ส่งโดยอัตโนมัติเพื่อตอบ PING pong ที่รับเข้ามาจะถูกละทิ้งโดยไม่มีการแจ้งเตือน

Instance attributes

request: microdot.Request

microdot.Request ต้นทาง -- ออบเจกต์เดียวกับที่ route handler ได้รับ

closed: bool

True เมื่อ close() ได้ทำงานแล้ว ตรวจสอบค่านี้เพื่อหลีกเลี่ยงการปิดการเชื่อมต่อซ้ำในขั้นตอนทำความสะอาด

Methods

async receive()

รอและคืนค่าข้อความถัดไปจาก client ประเภทค่าที่คืนตรงกับ frame opcode: str สำหรับ text frame, bytes สำหรับ binary frame frame ประเภท ping จะถูกตอบด้วย pong โดยอัตโนมัติ frame ประเภท pong จะถูกละทิ้งโดยไม่มีการแจ้งเตือน frame ประเภท close จะ raise WebSocketError ("Websocket connection closed")

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

ส่ง data ไปยัง client สตริงจะถูกส่งเป็น text frame, bytes จะถูกส่งเป็น binary frame; ส่ง opcode อย่างชัดเจนเพื่อแทนที่ค่าเริ่มต้น

async close()

ส่ง close frame และทำเครื่องหมายการเชื่อมต่อว่าปิดแล้ว ถูกเรียกโดยอัตโนมัติเมื่อ wrapper ของ with_websocket() สิ้นสุด

class WebSocketError

exception microdot.websocket.WebSocketError

raise ภายใน WebSocket.receive() เมื่อการเชื่อมต่อสิ้นสุดหรือมีการละเมิดโปรโตคอล ใช้ใน route เพื่อตรวจจับการตัดการเชื่อมต่อของ client ตามปกติ:

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

Module-level decorators

microdot.websocket.with_websocket(f)

Decorator ที่แปลง route ให้เป็น WebSocket endpoint handler จะรับ request และออบเจกต์ 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)

อายุการทำงานของ handler เท่ากับอายุการเชื่อมต่อ การ return, raise หรือการตัดการเชื่อมต่อของ client จะปิด WebSocket อย่างสะอาด

async microdot.websocket.websocket_upgrade(request)

ตัวช่วย upgrade ระดับต่ำ ใช้ภายใน route เมื่อการ upgrade ควรเกิดขึ้นแบบมีเงื่อนไข -- เช่น เฉพาะหลังจากการตรวจสอบสิทธิ์ผ่าน:

@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 ที่ถูก upgrade แล้ว handler ต้องคืนค่า microdot.Response.already_handled (หรือ raise) เมื่อดำเนินการเสร็จ -- microdot ได้เข้าควบคุม socket แล้ว

การใช้งานรองรับ text และ binary opcode มาตรฐาน, ping / pong และการปิดการเชื่อมต่ออย่างสะอาด Fragmented (continuation) frame ไม่ได้รับการรองรับ -- แต่ละข้อความถูกส่งเป็น frame เดียว ซึ่งเหมาะสมสำหรับแอปพลิเคชันกล้องที่ส่งข้อความขนาดเล็กทั่วไป