我需要一个运行时间较长的Websocket客户端,该客户端从Websocket服务器接收推送消息,并且需要监视客户端的连接状态:如果连接断开,则需要查找。
我的方法是定期记录一个常量字符串,如果未检测到日志消息,则触发警报。
我的想法:1)有一个websocket客户端,可以响应不规则的传入消息。和2)同时有循环,当websocket客户端抛出ConnectionClosed异常时,该循环停止记录消息。
我对新的3.5异步语法很感兴趣。此websocket实现专门基于asyncio。文档中的客户端看起来完全像我所需要的。
但是,我不知道如何添加,做我的日志语句第二协程,并以某种方式当WebSocket连接抛出ConnectionClosed停止。
这是开始对话的方法,但是不起作用,因为alive方法会阻止事件循环。我正在寻找的是一种优雅的解决方案,可以同时运行这两种方法。
#!/usr/bin/env python import asyncio import logging import websockets logger = logging.getLogger(__name__) is_alive = True async def alive(): while is_alive: logger.info('alive') await asyncio.sleep(300) async def async_processing(): async with websockets.connect('ws://localhost:8765') as websocket: while True: try: message = await websocket.recv() print(message) except websockets.exceptions.ConnectionClosed: print('ConnectionClosed') is_alive = False break asyncio.get_event_loop().run_until_complete(alive()) asyncio.get_event_loop().run_until_complete(async_processing())
实际上,run_until_complete这里阻塞了,因为它一直等到alive完成。
run_until_complete
您可以通过2个步骤解决它:
asyncio.ensure_future
asyncio.wait
tasks = [ asyncio.ensure_future(alive()), asyncio.ensure_future(async_processing()) ] asyncio.get_event_loop().run_until_complete(asyncio.wait(tasks))
由于@Vincent提到wait接受任务,因此ensure_future是不必要的:
asyncio.get_event_loop().run_until_complete(asyncio.wait([ alive(), async_processing() ]))