Bạn không thể sử dụng socket.settimeout()
, vì thiết bị được thiết kế để chặn IO và Tornado cung cấp IO không chặn.
Tornado được định hướng rất cao trên Web và HTTP IO và nó không cho phép lập trình mạng ở mức độ thấp mà không bị đau cực độ (nguồn IOStream
rất đáng sợ).
Cách tốt nhất để đặt thời gian chờ trên ổ cắm là sử dụng select.select()
, select.poll()
, v.v ... nhưng đó là một nỗi đau để tích hợp cách tiếp cận đó với Tornado.
Tôi đã quản lý để thực hiện các lần đọc với thời gian chờ sử dụng kết hợp của gen.with_timeout
và một bản hack bẩn để xóa trạng thái của luồng.
from tornado import gen
from tornado.ioloop import IOLoop
from tornado.tcpclient import TCPClient
timeout = 5
io_loop = IOLoop.current()
factory = TCPClient(io_loop=io_loop)
@gen.coroutine
def run():
stream = yield factory.connect('127.0.0.1', 1234)
try:
future = stream.read_bytes(128)
data = yield gen.with_timeout(
timeout=io_loop.time() + timeout,
future=future,
io_loop=io_loop,
)
except gen.TimeoutError:
# A dirty hack to cancel reading and to clear state of the stream, so
# stream will be available for reading in future
io_loop.remove_handler(stream.socket)
state = (stream._state & ~io_loop.READ)
stream._state = None
stream._read_callback = None
stream._read_future = None
stream._add_io_state(state)
Chúc may mắn!