Python 如何在异步IO服务器中实现超时?
下面是一个简单的echo服务器。但是如果客户端在10秒钟内没有发送任何内容,我想关闭连接Python 如何在异步IO服务器中实现超时?,python,python-3.x,python-asyncio,session-timeout,Python,Python 3.x,Python Asyncio,Session Timeout,下面是一个简单的echo服务器。但是如果客户端在10秒钟内没有发送任何内容,我想关闭连接 import asyncio async def process(reader: asyncio.StreamReader, writer: asyncio.StreamWriter): print("awaiting for data") line = await reader.readline() print(f"received {line}") writer.wr
import asyncio
async def process(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
print("awaiting for data")
line = await reader.readline()
print(f"received {line}")
writer.write(line)
print(f"sent {line}")
await writer.drain()
print(f"Drained")
async def timeout(task: asyncio.Task, duration):
print("timeout started")
await asyncio.sleep(duration)
print("client unresponsive, cancelling")
task.cancel()
print("task cancelled")
async def new_session(reader, writer):
print("new session started")
task = asyncio.create_task(process(reader, writer))
timer = asyncio.create_task(timeout(task, 10))
await task
print("task complete")
timer.cancel()
print("timer cancelled")
writer.close()
print("writer closed")
async def a_main():
server = await asyncio.start_server(new_session, port=8088)
await server.serve_forever()
if __name__ == '__main__':
asyncio.run(a_main())
如果客户端发送一条消息,它工作正常。但另一种情况是,当客户端处于静默状态时,它不工作
当客户端发送消息时:
new session started
awaiting for data
timeout started
received b'slkdfjsdlkfj\r\n'
sent b'slkdfjsdlkfj\r\n'
Drained
task complete
timer cancelled
writer closed
当客户端在打开连接后处于静默状态时
new session started
awaiting for data
timeout started
client unresponsive, cancelling
task cancelled
没有任务完成
,计时器取消
,写入程序关闭
更新 解决了问题,看起来任务实际上被取消了,但异常被默默忽略,通过捕获
cancelederror
async def new_session(reader, writer):
print("new session started")
task = asyncio.create_task(process(reader, writer))
timer = asyncio.create_task(timeout(task, 10))
try:
await task
except asyncio.CancelledError:
print(f"Task took too long and was cancelled by timer")
print("task complete")
timer.cancel()
print("timer cancelled")
writer.close()
print("writer closed")
第二部分仍然存在。有没有更好的方法来实现超时
更新2 使用
等待
完成代码。不再需要超时代码。接受以下支票:
我在建立连接时使用以下代码。我建议您的代码使用wait_for
fut = asyncio.open_connection( self.host, self.port, loop=self.loop )
try:
r, w = await asyncio.wait_for(fut, timeout=self.connection_timeout)
except asyncio.TimeoutError:
pass
有没有更好的方法来实现超时
您可以使用而不是
超时
。它具有类似的语义,但已经附带了asyncio。此外,您还可以等待它返回的未来,以检测是否发生超时。您可以使用asyncio。请等待而不是timeout
@user4815162342谢谢。是否要将其添加为答案?我会接受。open\u连接
是指当您是客户时。问题是服务器。这是一个如何使用wait_的例子,wait_是pythonic解决方案,用于您想要做的事情。我不知道它可以用于任何可等待的事情。向上投票。
fut = asyncio.open_connection( self.host, self.port, loop=self.loop )
try:
r, w = await asyncio.wait_for(fut, timeout=self.connection_timeout)
except asyncio.TimeoutError:
pass