Tornado 基于基本IOStream的 TCP 服務(wù)器

2022-03-10 11:53 更新

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

一個(gè)非阻塞的單線程 TCP 服務(wù)器。

要使用 ?TCPServer?,請(qǐng)定義一個(gè)覆蓋 ?handle_stream方法的子類。 例如,一個(gè)簡(jiǎn)單的echo服務(wù)器可以這樣定義:

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

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

要使此服務(wù)器為 SSL 流量提供服務(wù),請(qǐng)發(fā)送帶有 ?ssl.SSLContext? 對(duì)象的 ?ssl_options? 關(guān)鍵字參數(shù)。 為了與舊版本的 Python 兼容,?ssl_options? 也可能是 ?ssl.wrap_socket? 方法的關(guān)鍵字參數(shù)字典。:

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初始化遵循以下三種模式之一:

1、?listen?:簡(jiǎn)單的單進(jìn)程:

server = TCPServer()
server.listen(8888)
IOLoop.current().start()

2、?bind?/?start?:簡(jiǎn)單的多進(jìn)程:

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

使用此接口時(shí),不得將 ?IOLoop傳遞給 ?TCPServer構(gòu)造函數(shù)。 ?start將始終在默認(rèn)單例 ?IOLoop上啟動(dòng)服務(wù)器。

3、?add_sockets?:先進(jìn)的多進(jìn)程:

sockets = bind_sockets(8888)
tornado.process.fork_processes(0)
server = TCPServer()
server.add_sockets(sockets)
IOLoop.current().start()

?add_sockets接口更復(fù)雜,但它可以與 ?tornado.process.fork_processes? 一起使用,以便在分叉發(fā)生時(shí)為您提供更大的靈活性。 如果您想以非 ?bind_sockets的方式創(chuàng)建偵聽(tīng)套接字,?add_sockets也可用于單進(jìn)程服務(wù)器。

3.1 版中的新功能:?max_buffer_size ?參數(shù)。

在 5.0 版更改: ?io_loop? 參數(shù)已被刪除。

listen(port: int, address: str = '') → None

開(kāi)始接受給定端口上的連接。

可以多次調(diào)用此方法來(lái)偵聽(tīng)多個(gè)端口。 監(jiān)聽(tīng)立即生效; 之后無(wú)需調(diào)用 ?TCPServer.start?。 但是,必須啟動(dòng) ?IOLoop?

add_sockets(sockets: Iterable[socket.socket]) → None。

使此服務(wù)器開(kāi)始接受給定套接字上的連接。

?sockets參數(shù)是一個(gè)套接字對(duì)象列表,例如由 ?bind_sockets返回的那些。 ?add_sockets通常與該方法和 ?tornado.process.fork_processes 結(jié)合使用,以更好地控制多進(jìn)程服務(wù)器的初始化。

add_socket(socket: socket.socket) → None

?add_sockets的單一版本。 采用單個(gè)套接字對(duì)象。

bind(port: int, address: Optional[str] = None, family: socket.AddressFamily = <AddressFamily.AF_UNSPEC: 0>, backlog: int = 128, reuse_port: bool = False) → None

將此服務(wù)器綁定到給定地址上的給定端口。

要啟動(dòng)服務(wù)器,請(qǐng)調(diào)用 ?start?。 如果您想在單個(gè)進(jìn)程中運(yùn)行此服務(wù)器,您可以調(diào)用 ?listen作為綁定和啟動(dòng)調(diào)用序列的快捷方式。

地址可以是 IP 地址或主機(jī)名。 如果是主機(jī)名,服務(wù)器將偵聽(tīng)與該名稱關(guān)聯(lián)的所有 IP 地址。 Address 可以是空字符串或 None 以偵聽(tīng)所有可用接口。 Family 可以設(shè)置為 ?socket.AF_INET? 或 ?socket.AF_INET6? 以限制 IPv4 或 IPv6 地址,否則將使用兩者(如果可用)。

?backlog參數(shù)與 ?socket.listen? 的含義相同。 重用端口參數(shù)與 ?bind_sockets? 具有相同的含義。

在開(kāi)始偵聽(tīng)多個(gè)端口或接口之前,可能會(huì)多次調(diào)用此方法。

在 4.4 版更改: 添加了 ?reuse_port參數(shù)。

start(num_processes: Optional[int] = 1, max_restarts: Optional[int] = None) → None

在 ?IOLoop中啟動(dòng)此服務(wù)器。

默認(rèn)情況下,我們?cè)谶@個(gè)進(jìn)程中運(yùn)行服務(wù)器,并且不會(huì)派生任何額外的子進(jìn)程。

如果 ?num_processes為 ?None或 <= 0,我們會(huì)檢測(cè)這臺(tái)機(jī)器上可用的內(nèi)核數(shù)量并派生該數(shù)量的子進(jìn)程。 如果給定 ?num_processes并且 > 1,我們將分叉特定數(shù)量的子進(jìn)程。

由于我們使用進(jìn)程而不是線程,因此任何服務(wù)器代碼之間都沒(méi)有共享內(nèi)存。

請(qǐng)注意,多個(gè)進(jìn)程與 ?autoreload模塊(或 ?tornado.web.Application? 的 ?autoreload=True? 選項(xiàng),當(dāng) ?debug=True? 時(shí)默認(rèn)為 ?True?)不兼容。 當(dāng)使用多個(gè)進(jìn)程時(shí),在調(diào)用 ?TCPServer.start(n)之前不能創(chuàng)建或引用任何 ?IOLoop?。

Windows 不支持除 1 以外的 ?num_processes值。

?max_restarts參數(shù)被傳遞給 ?fork_processes?。

在 6.0 版更改: 添加了 ?max_restarts參數(shù)。

stop() → None

停止偵聽(tīng)新連接。

在服務(wù)器停止后,當(dāng)前正在進(jìn)行的請(qǐng)求可能仍會(huì)繼續(xù)。

handle_stream(stream: tornado.iostream.IOStream, address: tuple) → Optional[Awaitable[None]]

重寫以處理來(lái)自傳入連接的新 ?IOStream?。

這個(gè)方法可能是協(xié)程; 如果是這樣,它將記錄異步引發(fā)的任何異常。 此協(xié)程不會(huì)阻止接受傳入連接。

如果此 ?TCPServer配置為 ?SSL?,則可能會(huì)在 ?SSL握手完成之前調(diào)用 ?handle_stream?。 如果您需要驗(yàn)證客戶端的證書或使用 ?NPN?/?ALPN?,請(qǐng)使用 ?SSLIOStream.wait_for_handshake?。

在 4.2 版更改: 添加了將此方法作為協(xié)程的選項(xiàng)。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)