tornado.tcpserver — 基本的なIOStreamベースのTCPサーバー

ノンブロッキングのシングルスレッドTCPサーバー。

class tornado.tcpserver.TCPServer(ssl_options: Optional[Union[Dict[str, Any], SSLContext]] = None, max_buffer_size: Optional[int] = None, read_chunk_size: Optional[int] = None)[ソース]

ノンブロッキングのシングルスレッドTCPサーバー。

TCPServerを使用するには、handle_streamメソッドをオーバーライドするサブクラスを定義します。たとえば、単純なエコーサーバーは次のように定義できます。

from tornado.tcpserver import TCPServer
from tornado.iostream import StreamClosedError

class EchoServer(TCPServer):
    async def handle_stream(self, stream, address):
        while True:
            try:
                data = await stream.read_until(b"\n") await
                stream.write(data)
            except StreamClosedError:
                break

このサーバーでSSLトラフィックを処理するには、ssl_optionsキーワード引数にssl.SSLContextオブジェクトを渡します。旧バージョンのPythonとの互換性のため、ssl_optionsは、ssl.SSLContext.wrap_socketメソッドのキーワード引数の辞書である場合もあります。

ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_ctx.load_cert_chain(os.path.join(data_dir, "mydomain.crt"),
                        os.path.join(data_dir, "mydomain.key"))
TCPServer(ssl_options=ssl_ctx)

TCPServerの初期化は、次の3つのパターンのいずれかに従います。

  1. listen: シングルプロセス

    async def main():
        server = TCPServer()
        server.listen(8888)
        await asyncio.Event.wait()
    
    asyncio.run(main())
    

    この例では、それ自体で複数のプロセスを作成しませんが、reuse_port=True引数がlisten()に渡されると、プログラムを複数回実行して、マルチプロセスサービスを作成できます。

  2. add_sockets: マルチプロセス

    sockets = bind_sockets(8888)
    tornado.process.fork_processes(0)
    async def post_fork_main():
        server = TCPServer()
        server.add_sockets(sockets)
        await asyncio.Event().wait()
    asyncio.run(post_fork_main())
    

    add_socketsインターフェースはより複雑ですが、tornado.process.fork_processesと一緒に使用して、単一の親からフォークされたすべてのワーカープロセスでマルチプロセスサービスを実行できます。add_socketsは、bind_sockets以外の方法でリスニングソケットを作成する場合、シングルプロセスサーバーでも使用できます。

    このパターンを使用する場合、イベントループに触れるものはfork_processesの前に実行できないことに注意してください。

  3. bind/start: 単純な**非推奨**マルチプロセス

    server = TCPServer()
    server.bind(8888)
    server.start(0)  # Forks multiple sub-processes
    IOLoop.current().start()
    

    このパターンは、Python 3.10以降非推奨になっているasyncioモジュールのインターフェースが必要なため、非推奨になりました。startメソッドで複数のプロセスを作成するサポートは、将来のTornadoバージョンで削除されます。

バージョン 3.1 で追加: max_buffer_size引数。

バージョン 5.0 で変更: io_loop引数が削除されました。

listen(port: int, address: Optional[str] = None, family: AddressFamily = AddressFamily.AF_UNSPEC, backlog: int = 128, flags: Optional[int] = None, reuse_port: bool = False) None[ソース]

指定されたポートでの接続の受け入れを開始します。

このメソッドは、複数のポートでリッスンするために複数回呼び出すことができます。listen は即座に有効になります。その後でTCPServer.start を呼び出す必要はありません。ただし、イベントループがまだ実行されていない場合は、開始する必要があります。

すべての引数は、tornado.netutil.bind_sockets と同じ意味を持ちます。

バージョン 6.2 で変更: tornado.netutil.bind_sockets に合わせて、familybacklogflags、および reuse_port 引数が追加されました。

add_sockets(sockets: Iterable[socket]) None[ソース]

このサーバーが、指定されたソケットでの接続の受け入れを開始するようにします。

sockets パラメータは、bind_sockets によって返されるようなソケットオブジェクトのリストです。add_sockets は通常、マルチプロセスサーバーの初期化をより詳細に制御するために、そのメソッドとtornado.process.fork_processes と組み合わせて使用されます。

add_socket(socket: socket) None[ソース]

add_sockets の単数形バージョンです。単一のソケットオブジェクトを受け取ります。

bind(port: int, address: Optional[str] = None, family: AddressFamily = AddressFamily.AF_UNSPEC, backlog: int = 128, flags: Optional[int] = None, reuse_port: bool = False) None[ソース]

このサーバーを、指定されたアドレスの指定されたポートにバインドします。

サーバーを起動するには、start を呼び出します。このサーバーを単一プロセスで実行する場合は、bindstart の呼び出しシーケンスのショートカットとして、listen を呼び出すことができます。

アドレスには、IP アドレスまたはホスト名のいずれかを指定できます。ホスト名の場合、サーバーはその名前に関連付けられたすべての IP アドレスでリッスンします。アドレスには、使用可能なすべてのインターフェースでリッスンするために、空の文字列または None を指定できます。ファミリーは、IPv4 または IPv6 アドレスに制限するために、socket.AF_INET または socket.AF_INET6 のいずれかに設定できます。それ以外の場合は、利用可能な場合は両方が使用されます。

backlog 引数は、socket.listen と同じ意味を持ちます。reuse_port 引数は、bind_sockets と同じ意味を持ちます。

このメソッドは、複数のポートまたはインターフェースでリッスンするために、start の前に複数回呼び出すことができます。

バージョン 4.4 で変更: reuse_port 引数が追加されました。

バージョン 6.2 で変更: bind_sockets に合わせて、flags 引数が追加されました。

バージョン 6.2 で非推奨: bind()start() の代わりに、listen() または add_sockets() のいずれかを使用してください。

start(num_processes: Optional[int] = 1, max_restarts: Optional[int] = None) None[ソース]

このサーバーをIOLoop で起動します。

デフォルトでは、このプロセスでサーバーを実行し、追加の子プロセスをフォークしません。

num_processes が None または <= 0 の場合、このマシンで使用可能なコア数を検出し、その数の子プロセスをフォークします。num_processes が指定されていて > 1 の場合、その特定数のサブプロセスをフォークします。

スレッドではなくプロセスを使用するため、サーバーコード間で共有メモリはありません。

複数のプロセスは、自動リロードモジュール(または、autoreload=Trueオプションで、tornado.web.Application、これはdebug=TrueのときにデフォルトでTrueになります)と互換性がないことに注意してください。複数のプロセスを使用する場合、TCPServer.start(n)の呼び出し後まで、IOLoopを作成したり参照したりすることはできません。

num_processesの値が1以外の場合、Windowsではサポートされていません。

max_restarts引数は、fork_processesに渡されます。

バージョン 6.0 で変更: max_restarts引数が追加されました。

バージョン 6.2 で非推奨: bind()start() の代わりに、listen() または add_sockets() のいずれかを使用してください。

stop() None[ソース]

新しい接続のリスンを停止します。

サーバーが停止した後でも、現在進行中のリクエストは継続される可能性があります。

handle_stream(stream: IOStream, address: tuple) Optional[Awaitable[None]][ソース]

受信接続からの新しいIOStreamを処理するためにオーバーライドします。

このメソッドはコルーチンにすることができます。その場合、非同期的に発生した例外はログに記録されます。このコルーチンによって、受信接続の受け入れがブロックされることはありません。

このTCPServerがSSL用に構成されている場合、handle_streamはSSLハンドシェイクが完了する前に呼び出される可能性があります。クライアントの証明書を検証したり、NPN/ALPNを使用する必要がある場合は、SSLIOStream.wait_for_handshakeを使用してください。

バージョン 4.2 で変更: このメソッドをコルーチンにするオプションが追加されました。