问题
I'm using AsyncIO and the Websockets module to create two concurrent tasks in Python, each one connects to a websocket server and receives messages.
I'm trying to create a system where, when a task did not receive messages for more than 4 seconds, it must close the connection and the task, but i'm having an hard time figuring that out. Can anyone help me out on this?
Here is what i tried:
async def connect(URI):
async with websockets.client.connect(URI) as ws:
LastUpdate = time.time()
while time.time() - LastUpdate < 4:
LastUpdate = time.time()
await ws.recv()
print('Not receiving updates anymore')
async def main():
Tasks = [asyncio.create_task(connect('URI1')), asyncio.create_task(connect('URI2'))]
await asyncio.gather(*Tasks)
Here, main
creates two concurrent tasks and runs both of them. connect
takes care of connecting and receiving messages. What i tried to do is to break the while loop when the last update was more than 4 seconds ago, but that didn't work since the loop doesn't get broken.
回答1:
You can use asyncio.wait_for:
async def connect(URI):
async with websockets.client.connect(URI) as ws:
while True:
try:
msg = await asyncio.wait_for(ws.recv(), 4)
except asyncio.TimeoutError:
break
# do something with msg
print('Not receiving updates anymore')
回答2:
There are a couple ways to do this.
- You can set a timeout in the package you are using within the async routine.
- You can use asyncio and terminate tasks when they reach a timeout.
- You can use non-blocking sockets for all operations, and not use asyncio at all, but use select() or poll(). This is very efficient but a lot more complex.
I would go in this order, the first one being the easiest and most preferred in most cases. Websockets seem to handle timeouts: https://github.com/websocket-client/websocket-client/blob/29c15714ac9f5272e1adefc9c99b83420b409f63/websocket/_socket.py#L99
You probably want to set a timeout on the socket. Generally this is done with https://docs.python.org/3.8/library/socket.html#socket.socket.settimeout
I suppose websockets expose this functionality somewhere though, but I am not familiar with it.
来源:https://stackoverflow.com/questions/64044426/close-a-task-in-python-based-on-condition