一個非阻塞的單線程 TCP 服務器。
要使用 ?TCPServer
?,請定義一個覆蓋 ?handle_stream
方法的子類。 例如,一個簡單的echo服務器可以這樣定義:
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
要使此服務器為 SSL 流量提供服務,請發(fā)送帶有 ?ssl.SSLContext
? 對象的 ?ssl_options
? 關鍵字參數。 為了與舊版本的 Python 兼容,?ssl_options
? 也可能是 ?ssl.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
初始化遵循以下三種模式之一:
1、?listen
?:簡單的單進程:
server = TCPServer()
server.listen(8888)
IOLoop.current().start()
2、?bind
?/?start
?:簡單的多進程:
server = TCPServer()
server.bind(8888)
server.start(0) # Forks multiple sub-processes
IOLoop.current().start()
使用此接口時,不得將 ?IOLoop
傳遞給 ?TCPServer
構造函數。 ?start
將始終在默認單例 ?IOLoop
上啟動服務器。
3、?add_sockets
?:先進的多進程:
sockets = bind_sockets(8888)
tornado.process.fork_processes(0)
server = TCPServer()
server.add_sockets(sockets)
IOLoop.current().start()
?add_sockets
接口更復雜,但它可以與 ?tornado.process.fork_processes
? 一起使用,以便在分叉發(fā)生時為您提供更大的靈活性。 如果您想以非 ?bind_sockets
的方式創(chuàng)建偵聽套接字,?add_sockets
也可用于單進程服務器。
3.1 版中的新功能:?max_buffer_size
?參數。
在 5.0 版更改: ?io_loop
? 參數已被刪除。
開始接受給定端口上的連接。
可以多次調用此方法來偵聽多個端口。 監(jiān)聽立即生效; 之后無需調用 ?TCPServer.start
?。 但是,必須啟動 ?IOLoop
?
使此服務器開始接受給定套接字上的連接。
?sockets
參數是一個套接字對象列表,例如由 ?bind_sockets
返回的那些。 ?add_sockets
通常與該方法和 ?tornado.process.fork_processes
結合使用,以更好地控制多進程服務器的初始化。
?add_sockets
的單一版本。 采用單個套接字對象。
將此服務器綁定到給定地址上的給定端口。
要啟動服務器,請調用 ?start
?。 如果您想在單個進程中運行此服務器,您可以調用 ?listen
作為綁定和啟動調用序列的快捷方式。
地址可以是 IP 地址或主機名。 如果是主機名,服務器將偵聽與該名稱關聯的所有 IP 地址。 Address 可以是空字符串或 None 以偵聽所有可用接口。 Family 可以設置為 ?socket.AF_INET
? 或 ?socket.AF_INET6
? 以限制 IPv4 或 IPv6 地址,否則將使用兩者(如果可用)。
?backlog
參數與 ?socket.listen
? 的含義相同。 重用端口參數與 ?bind_sockets
? 具有相同的含義。
在開始偵聽多個端口或接口之前,可能會多次調用此方法。
在 4.4 版更改: 添加了 ?reuse_port
參數。
在 ?IOLoop
中啟動此服務器。
默認情況下,我們在這個進程中運行服務器,并且不會派生任何額外的子進程。
如果 ?num_processes
為 ?None
或 <= 0,我們會檢測這臺機器上可用的內核數量并派生該數量的子進程。 如果給定 ?num_processes
并且 > 1,我們將分叉特定數量的子進程。
由于我們使用進程而不是線程,因此任何服務器代碼之間都沒有共享內存。
請注意,多個進程與 ?autoreload
模塊(或 ?tornado.web.Application
? 的 ?autoreload=True
? 選項,當 ?debug=True
? 時默認為 ?True
?)不兼容。 當使用多個進程時,在調用 ?TCPServer.start(n)
之前不能創(chuàng)建或引用任何 ?IOLoop
?。
Windows 不支持除 1 以外的 ?num_processes
值。
?max_restarts
參數被傳遞給 ?fork_processes
?。
在 6.0 版更改: 添加了 ?max_restarts
參數。
停止偵聽新連接。
在服務器停止后,當前正在進行的請求可能仍會繼續(xù)。
重寫以處理來自傳入連接的新 ?IOStream
?。
這個方法可能是協程; 如果是這樣,它將記錄異步引發(fā)的任何異常。 此協程不會阻止接受傳入連接。
如果此 ?TCPServer
配置為 ?SSL
?,則可能會在 ?SSL
握手完成之前調用 ?handle_stream
?。 如果您需要驗證客戶端的證書或使用 ?NPN
?/?ALPN
?,請使用 ?SSLIOStream.wait_for_handshake
?。
在 4.2 版更改: 添加了將此方法作為協程的選項。
更多建議: