一個(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ù)已被刪除。
開(kāi)始接受給定端口上的連接。
可以多次調(diào)用此方法來(lái)偵聽(tīng)多個(gè)端口。 監(jiān)聽(tīng)立即生效; 之后無(wú)需調(diào)用 ?TCPServer.start
?。 但是,必須啟動(dòng) ?IOLoop
?
使此服務(wù)器開(kāi)始接受給定套接字上的連接。
?sockets
參數(shù)是一個(gè)套接字對(duì)象列表,例如由 ?bind_sockets
返回的那些。 ?add_sockets
通常與該方法和 ?tornado.process.fork_processes
結(jié)合使用,以更好地控制多進(jìn)程服務(wù)器的初始化。
?add_sockets
的單一版本。 采用單個(gè)套接字對(duì)象。
將此服務(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ù)。
在 ?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ù)。
停止偵聽(tīng)新連接。
在服務(wù)器停止后,當(dāng)前正在進(jìn)行的請(qǐng)求可能仍會(huì)繼續(xù)。
重寫以處理來(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)。
更多建議: