tornado.websocket
— ブラウザとの双方向通信¶
WebSocket プロトコルの実装。
WebSocket は、ブラウザとサーバー間の双方向通信を可能にします。WebSocket は、すべての主要ブラウザの現在のバージョンでサポートされています。
このモジュールは、RFC 6455 で定義されている WebSocket プロトコルの最終バージョンを実装しています。
バージョン 4.0 で変更: ドラフト 76 プロトコルバージョンのサポートを削除しました。
- class tornado.websocket.WebSocketHandler(application: Application, request: HTTPServerRequest, **kwargs: Any)[ソース]¶
基本的な WebSocket ハンドラを作成するには、このクラスをサブクラス化します。
受信メッセージを処理するには
on_message
をオーバーライドし、クライアントにメッセージを送信するにはwrite_message
を使用します。open
とon_close
をオーバーライドして、接続の開始と終了を処理することもできます。カスタムアップグレードレスポンスヘッダーは、
set_default_headers
またはprepare
をオーバーライドすることで送信できます。JavaScript インターフェースの詳細は、http://dev.w3.org/html5/websockets/ を参照してください。プロトコルは http://tools.ietf.org/html/rfc6455 で規定されています。
受信したすべてのメッセージをクライアントにエコーバックする WebSocket ハンドラの例を次に示します
class EchoWebSocket(tornado.websocket.WebSocketHandler): def open(self): print("WebSocket opened") def on_message(self, message): self.write_message(u"You said: " + message) def on_close(self): print("WebSocket closed")
WebSocket は標準の HTTP 接続ではありません。「ハンドシェイク」は HTTP ですが、ハンドシェイク後は、プロトコルはメッセージベースです。そのため、Tornado HTTP 機能のほとんどは、このタイプのハンドラでは使用できません。使用できる通信方法は、
write_message()
、ping()
、close()
のみです。同様に、リクエストハンドラクラスは、get()
やpost()
ではなく、open()
メソッドを実装する必要があります。上記のハンドラをアプリケーションの
/websocket
にマッピングすると、JavaScript で次のように呼び出すことができますvar ws = new WebSocket("ws://localhost:8888/websocket"); ws.onopen = function() { ws.send("Hello, world"); }; ws.onmessage = function (evt) { alert(evt.data); };
このスクリプトは、「You said: Hello, world」というアラートボックスを表示します。
Webブラウザは、JavaScript からの他のネットワークアクセスを制御する同一オリジンポリシーを使用する代わりに、任意のサイトが他のサイトへの WebSocket 接続を開くことを許可します。これは驚くべきことであり、潜在的なセキュリティホールであるため、Tornado 4.0 以降、
WebSocketHandler
は、クロスオリジン WebSocket を受信したいアプリケーションがcheck_origin
メソッドをオーバーライドすることによってオプトインすることを要求します(詳細は、そのメソッドのドキュメントを参照してください)。そうしないと、WebSocket 接続時に 403 エラーが発生する可能性が高くなります。自己署名証明書を使用してセキュア WebSocket 接続(
wss://
)を使用する場合、ブラウザからの接続は、「この証明書を受け入れる」ダイアログを表示したいが、表示する場所がないため失敗する可能性があります。 WebSocket 接続が成功する前に、同じ証明書を使用して通常の HTML ページにアクセスして、証明書を受け入れる必要があります。アプリケーション設定
websocket_ping_interval
にゼロ以外の値が設定されている場合、ping が定期的に送信され、websocket_ping_timeout
前に応答が受信されない場合、接続は閉じられます。アプリケーション設定
websocket_max_message_size
(デフォルト 10MiB)を超えるメッセージは受け入れられません。バージョン 4.5 で変更:
websocket_ping_interval
、websocket_ping_timeout
、websocket_max_message_size
が追加されました。
イベントハンドラ¶
- WebSocketHandler.open(*args: str, **kwargs: str) Optional[Awaitable[None]] [ソース]¶
新しい WebSocket が開かれたときに呼び出されます。
open
への引数は、tornado.web.RequestHandler.get
への引数と同様に、tornado.web.URLSpec
正規表現から抽出されます。open
はコルーチンです。on_message
は、open
が戻るまで呼び出されません。バージョン 5.1 で変更:
open
はコルーチンです。
- WebSocketHandler.on_message(message: Union[str, bytes]) Optional[Awaitable[None]] [source]¶
WebSocket で受信したメッセージを処理します。
このメソッドはオーバーライドする必要があります。
バージョン 4.5 で変更:
on_message
はコルーチンにすることができます。
- WebSocketHandler.on_close() None [source]¶
WebSocket が閉じられたときに呼び出されます。
接続が正常に閉じられ、ステータスコードまたは理由のフレーズが提供された場合、これらの値は属性
self.close_code
およびself.close_reason
として利用できます。バージョン 4.0 で変更:
close_code
およびclose_reason
属性が追加されました。
- WebSocketHandler.select_subprotocol(subprotocols: List[str]) Optional[str] [source]¶
サブプロトコルネゴシエーションを実装するには、オーバーライドします。
subprotocols
は、クライアントによって提案されたサブプロトコルを識別する文字列のリストです。 このメソッドをオーバーライドして、それらの文字列のいずれかを返して選択するか、None
を返してサブプロトコルを選択しないようにすることができます。サブプロトコルの選択に失敗しても、接続は自動的に中止されません。ただし、クライアントは、提案されたサブプロトコルのいずれも選択されなかった場合、接続を閉じる場合があります。
リストが空の場合、このメソッドは None を返す必要があります。 このメソッドは、サブプロトコルが提案されていない場合でも、常に正確に 1 回呼び出されるため、ハンドラはこの事実を通知できます。
バージョン 5.1 で変更: 以前は、クライアントによってサブプロトコルが提案されていない場合、このメソッドは空のリストではなく、空の文字列を含むリストで呼び出されていました。
- WebSocketHandler.selected_subprotocol¶
select_subprotocol
によって返されるサブプロトコル。バージョン 5.1 で追加。
出力¶
- WebSocketHandler.write_message(message: Union[bytes, str, Dict[str, Any]], binary: bool = False) Future[None] [source]¶
指定されたメッセージをこの WebSocket のクライアントに送信します。
メッセージは、文字列または辞書(json としてエンコードされます)です。
binary
引数が false の場合、メッセージは utf8 として送信されます。 バイナリモードでは、任意のバイト文字列が許可されます。接続がすでに閉じている場合は、
WebSocketClosedError
を発生させます。 フロー制御に使用できるFuture
を返します。バージョン 3.2 で変更:
WebSocketClosedError
が追加されました(以前は、閉じた接続はAttributeError
を発生させていました)バージョン 4.3 で変更: フロー制御に使用できる
Future
を返します。バージョン 5.0 で変更:
WebSocketClosedError
を一貫して発生させます。 以前は、StreamClosedError
を発生させる場合がありました。
- WebSocketHandler.close(code: Optional[int] = None, reason: Optional[str] = None) None [source]¶
この WebSocket を閉じます。
クローズハンドシェイクが成功すると、ソケットは閉じられます。
code
は、RFC 6455 セクション 7.4.1 で定義されている値から取得した、数値ステータスコードです。reason
は、接続が閉じられる理由に関するテキストメッセージです。これらの値はクライアントが利用できますが、WebSocket プロトコルでは解釈されません。バージョン 4.0 で変更:
code
とreason
引数が追加されました。
設定¶
- WebSocketHandler.check_origin(origin: str) bool [source]¶
代替オリジンを許可するためのサポートを有効にするには、オーバーライドします。
origin
引数は、Origin
HTTP ヘッダーの値、つまりこのリクエストを開始した URL です。このヘッダーを送信しないクライアントに対しては、このメソッドは呼び出されません。そのようなリクエストは常に許可されます(WebSocket を実装するすべてのブラウザがこのヘッダーをサポートしており、ブラウザ以外のクライアントには同じクロスサイトセキュリティ上の懸念がないためです)。リクエストを受け入れる場合は
True
を、拒否する場合はFalse
を返します。デフォルトでは、このホスト以外のホストでオリジンを持つすべてのリクエストを拒否します。これは、WebSocket は通常の同一オリジンポリシーをバイパスすることができ、CORS ヘッダーを使用しないため、ブラウザに対するクロスサイトスクリプティング攻撃に対するセキュリティ保護です。
警告
これは重要なセキュリティ対策です。セキュリティへの影響を理解せずに無効にしないでください。特に、認証が Cookie ベースの場合、
check_origin()
で許可されるオリジンを制限するか、WebSocket 接続に独自の XSRF のような保護を実装する必要があります。詳細については、これらの 記事 を参照してください。すべてのクロスオリジントラフィックを受け入れるには(Tornado 4.0 より前のデフォルト)、このメソッドをオーバーライドして常に
True
を返すようにします。def check_origin(self, origin): return True
サイトの任意のサブドメインからの接続を許可するには、次のようにします。
def check_origin(self, origin): parsed_origin = urllib.parse.urlparse(origin) return parsed_origin.netloc.endswith(".mydomain.com")
バージョン 4.0 での新機能。
- WebSocketHandler.get_compression_options() Optional[Dict[str, Any]] [source]¶
接続の圧縮オプションを返すには、オーバーライドします。
このメソッドが None(デフォルト)を返すと、圧縮は無効になります。辞書(空の辞書でも)を返すと、圧縮は有効になります。辞書の内容を使用して、次の圧縮オプションを制御できます。
compression_level
は圧縮レベルを指定します。mem_level
は、内部圧縮状態に使用されるメモリ量を指定します。これらのパラメータの詳細は、こちらに記載されています:https://docs.python.org/3.6/library/zlib.html#zlib.compressobj
バージョン 4.1 での新機能。
バージョン 4.5 で変更:
compression_level
とmem_level
が追加されました。
- WebSocketHandler.set_nodelay(value: bool) None [source]¶
このストリームの no-delay フラグを設定します。
デフォルトでは、送信されるパケット数を最小限に抑えるために、小さなメッセージが遅延したり、結合されたりする可能性があります。これにより、Nagle のアルゴリズムと TCP 遅延 ACK の相互作用により、200〜500ミリ秒の遅延が発生することがあります。帯域幅の使用量が増加する可能性がありますが、この遅延を 줄이려면、WebSocket 接続が確立されたら、
self.set_nodelay(True)
を呼び出します。詳細は、
BaseIOStream.set_nodelay
を参照してください。バージョン 3.1 での新機能。
その他¶
- WebSocketHandler.ping(data: Union[str, bytes] = b'') None [source]¶
リモートエンドに ping フレームを送信します。
data 引数を使用すると、少量のデータ(最大 125 バイト)を ping メッセージの一部として送信できます。すべての WebSocket 実装がこのデータをアプリケーションに公開するわけではないことに注意してください。
ping を手動で送信する代わりに、
websocket_ping_interval
アプリケーション設定の使用を検討してください。バージョン 5.1 で変更: data 引数がオプションになりました。
クライアントサイドのサポート¶
- tornado.websocket.websocket_connect(url: Union[str, HTTPRequest], callback: Optional[Callable[[Future[WebSocketClientConnection]], None]] = None, ...) Awaitable[WebSocketClientConnection] ¶
クライアント側の WebSocket サポート。
URL を受け取り、結果が
WebSocketClientConnection
である Future を返します。compression_options
は、WebSocketHandler.get_compression_options
の戻り値と同じように解釈されます。この接続は、2 つの動作スタイルをサポートしています。コルーチンスタイルでは、アプリケーションは通常、ループ内で
read_message
を呼び出します。conn = yield websocket_connect(url) while True: msg = yield conn.read_message() if msg is None: break # Do something with msg
コールバックスタイルでは、
on_message_callback
をwebsocket_connect
に渡します。どちらのスタイルでも、None
のメッセージは、接続が閉じられたことを示します。subprotocols
は、提案されたサブプロトコルを指定する文字列のリストです。選択されたプロトコルは、接続が完了したときに、接続オブジェクトのselected_subprotocol
属性で見つけることができます。バージョン 3.2 で変更: URL の代わりに
HTTPRequest
オブジェクトも受け入れるようになりました。バージョン 4.1 で変更:
compression_options
とon_message_callback
が追加されました。バージョン 4.5 で変更:
WebSocketHandler
と同じ意味を持つping_interval
、ping_timeout
、max_message_size
引数が追加されました。バージョン 5.0 で変更:
io_loop
引数 (バージョン 4.1 から非推奨) が削除されました。バージョン 5.1 で変更:
subprotocols
引数が追加されました。バージョン 6.3 で変更:
resolver
引数が追加されました。
- class tornado.websocket.WebSocketClientConnection(request: HTTPRequest, on_message_callback: Optional[Callable[[Union[None, str, bytes]], None]] = None, ... )¶
WebSocket クライアント接続。
このクラスは直接インスタンス化すべきではありません。代わりに
websocket_connect
関数を使用してください。- close(code: Optional[int] = None, reason: Optional[str] = None) None ¶
WebSocket 接続を閉じます。
code
とreason
については、WebSocketHandler.close
のドキュメントを参照してください。バージョン 3.2 での新機能。
バージョン 4.0 で変更:
code
とreason
引数が追加されました。
- write_message(...) Future[None] ¶
WebSocket サーバーにメッセージを送信します。
ストリームが閉じている場合、
WebSocketClosedError
を発生させます。フロー制御に使用できるFuture
を返します。バージョン 5.0 で変更: クローズされたストリームで発生する例外が
StreamClosedError
からWebSocketClosedError
に変更されました。
- read_message(callback: Optional[Callable[[Future[Union[None, str, bytes]]], None]] = None) Awaitable[Union[None, str, bytes]] [ソース]¶
WebSocket サーバーからメッセージを読み取ります。
WebSocket の初期化時に on_message_callback が指定されている場合、この関数はメッセージを返しません。
結果がメッセージである Future を返します。接続が閉じている場合は None を返します。callback 引数が指定されている場合、Future が準備完了になったときに、その Future を使用してコールバックが呼び出されます。
- ping(data: bytes = b'') None [ソース]¶
リモートエンドに ping フレームを送信します。
data 引数を使用すると、少量のデータ(最大 125 バイト)を ping メッセージの一部として送信できます。すべての WebSocket 実装がこのデータをアプリケーションに公開するわけではないことに注意してください。
ping を手動で送信する代わりに、
websocket_connect
へのping_interval
引数の使用を検討してください。バージョン 5.1 で追加。