microdot.websocket --- Hỗ trợ WebSocket

WebSocket là kết nối hai chiều liên tục qua HTTP -- sau giai đoạn bắt tay nâng cấp, client và server gửi và nhận các thông điệp đóng khung trên cùng một socket. Sử dụng khi camera và ứng dụng phía trình duyệt cần lưu lượng truy cập song công hoàn toàn mà SSE (đẩy một chiều) và polling HTTP thông thường không thể đáp ứng hiệu quả.

class WebSocket

class microdot.websocket.WebSocket(request)

Đối tượng xử lý mà route nhận được. Được truyền vào các handler như đối số thứ hai khi with_websocket() đang được sử dụng; không khởi tạo trực tiếp.

Thuộc tính lớp

max_message_length: int

Kích thước payload tối đa mà receive() sẽ chấp nhận. Các thông điệp lớn hơn giá trị này sẽ raise WebSocketError và đóng kết nối. 0 vô hiệu hóa kiểm tra (cần chú ý các cuộc tấn công cạn kiệt bộ nhớ nếu bạn đặt giá trị này). -1 (mặc định) sử dụng Request.max_body_length.

CONT: int

Opcode của continuation-frame, 0x0. Đánh dấu một frame tiếp nối payload của frame trước cho cùng một thông điệp. Microdot không tự tạo continuation frame (mỗi thông điệp được gửi đi như một frame duy nhất) và từ chối chúng khi nhận, nhưng hằng số này được tiết lộ cho các ứng dụng triển khai framing tùy chỉnh.

TEXT: int

Opcode của text-frame, 0x1. Opcode mà send() tự động chọn khi datastr; payload được mã hóa UTF-8 khi gửi đi.

BINARY: int

Opcode của binary-frame, 0x2. Opcode mà send() tự động chọn khi databytes / bytearray; payload được gửi nguyên vẹn.

CLOSE: int

Opcode của close-frame, 0x8. Được gửi bởi close(); việc nhận một close-frame sẽ raise WebSocketError ("Websocket connection closed") từ receive().

PING: int

Opcode của ping-frame, 0x9. Microdot tự động trả lời các ping đến bằng PONG tương ứng bên trong receive(); ứng dụng thường không quan sát thấy chúng.

PONG: int

Opcode của pong-frame, 0xA. Được gửi tự động để trả lời PING. Các pong đến bị loại bỏ im lặng.

Thuộc tính thực thể

request: microdot.Request

microdot.Request nguồn gốc -- cùng đối tượng mà route handler đã nhận.

closed: bool

True sau khi close() đã chạy. Kiểm tra để tránh đóng kết nối hai lần trong các đường dọn dẹp.

Phương thức

async receive()

Chờ và trả về thông điệp tiếp theo từ client. Kiểu trả về phụ thuộc vào opcode frame: str cho text frame, bytes cho binary frame. Các frame ping được tự động trả lời bằng pong; các frame pong bị loại bỏ im lặng; một frame close sẽ raise WebSocketError ("Websocket connection closed").

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

Gửi data đến client. Chuỗi được gửi dưới dạng text frame, bytes dưới dạng binary frame; truyền opcode tường minh để ghi đè.

async close()

Gửi một close frame và đánh dấu kết nối là đã đóng. Được gọi tự động khi trình bao bọc của with_websocket() thoát.

class WebSocketError

exception microdot.websocket.WebSocketError

Được raise bên trong WebSocket.receive() khi kết nối kết thúc hoặc giao thức bị vi phạm. Sử dụng trong một route để phát hiện client ngắt kết nối bình thường:

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

Decorator ở mức module

microdot.websocket.with_websocket(f)

Decorator biến một route thành điểm cuối WebSocket. Handler nhận request và một đối tượng 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)

Thời gian tồn tại của handler bằng với thời gian tồn tại của kết nối. Trả về, raise ngoại lệ, hoặc client ngắt kết nối sẽ đóng WebSocket một cách sạch sẽ.

async microdot.websocket.websocket_upgrade(request)

Hàm trợ giúp nâng cấp cấp thấp. Sử dụng bên trong một route khi việc nâng cấp cần xảy ra có điều kiện -- ví dụ: chỉ sau khi kiểm tra ủy quyền thành công:

@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())

Trả về WebSocket đã được nâng cấp. Handler phải trả về microdot.Response.already_handled (hoặc raise) sau khi hoàn thành -- microdot đã tiếp quản socket.

Phần triển khai hỗ trợ các opcode text và binary tiêu chuẩn, ping / pong, và đóng kết nối sạch sẽ. Các frame phân mảnh (continuation) không được hỗ trợ -- mỗi thông điệp được gửi như một frame duy nhất, phù hợp với các ứng dụng camera điển hình có thông điệp nhỏ.