microdot.websocket --- WebSocket サポート¶
WebSocket は HTTP 上の双方向の永続的な接続です。アップグレードハンドシェイクの後、クライアントとサーバーは同じソケット上でフレーム化されたメッセージを送受信します。SSE(一方向プッシュ)や通常の HTTP ポーリングでは安価に実現できない全二重通信が、カメラとブラウザ側アプリケーションの間で必要な場合に使用します。
class WebSocket¶
- class microdot.websocket.WebSocket(request)¶
ルートが受け取るハンドルです。
with_websocket()を使用している場合、ハンドラに 2 番目の引数として渡されます。直接構築しないでください。クラス属性
- max_message_length: int¶
receive()が受け入れる最大ペイロードサイズです。これを超えるメッセージはWebSocketErrorを発生させ、接続を閉じます。0を指定するとチェックが無効になります(これを設定する場合はメモリ枯渇攻撃に注意してください)。-1(デフォルト)はRequest.max_body_lengthを使用します。
- CONT: int¶
継続フレームのオペコード
0x0です。同じメッセージの前のフレームのペイロードを継続するフレームを示します。Microdot 自身は継続フレームを生成せず(各メッセージは単一のフレームとして送信されます)、受信時には拒否しますが、カスタムフレーミングを実装するアプリケーションのために定数が公開されています。
- TEXT: int¶
テキストフレームのオペコード
0x1です。data がstrの場合にsend()が自動的に選択するオペコードで、ペイロードは送出時に UTF-8 でエンコードされます。
- BINARY: int¶
バイナリフレームのオペコード
0x2です。data がbytes/bytearrayの場合にsend()が自動的に選択するオペコードで、ペイロードはそのまま送信されます。
- CLOSE: int¶
クローズフレームのオペコード
0x8です。close()によって送信されます。これを受信するとreceive()からWebSocketError("Websocket connection closed")が発生します。
- PING: int¶
ピングフレームのオペコード
0x9です。Microdot は受信したピングに対してreceive()内で自動的に対応するPONGで応答します。アプリケーションが通常これを観測することはありません。
インスタンス属性
- request: microdot.Request¶
発信元の
microdot.Requestです。ルートハンドラが受け取ったものと同じオブジェクトです。
メソッド
- async receive()¶
クライアントからの次のメッセージを待って返します。戻り値の型はフレームのオペコードに一致します。テキストフレームの場合は
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)¶
ルートを 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 はすでにソケットを引き継いでいます。
この実装は標準のテキストおよびバイナリのオペコード、ping / pong、および正常なクローズをサポートします。フラグメント化された(継続)フレームはサポートされません。各メッセージは単一のフレームとして送信されますが、これは小さなメッセージが典型的なカメラアプリケーションには適しています。