Python异步WebSocket客户端与异步定时器

8
我需要一个长时间运行的Websocket客户端,从Websocket服务器接收推送消息,并且需要监视客户端的连接状态:如果连接断开,我需要知道。
我的方法是定期记录一个常量字符串,并在未检测到日志消息时触发警报。
我的想法:1)拥有一个Websocket客户端,响应不规则的传入消息。并且2)同时有一个循环,当websocket客户端抛出ConnectionClosed异常时停止记录消息。
我对新的3.5 async语法感到困惑。此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())
1个回答

9
实际上,在这里 run_until_complete 是阻塞的,因为它等待直到 alive 完成。
您可以采取以下两个步骤解决此问题:
  1. 使用 asyncio.ensure_future 调度协程(立即运行而不等待结果),每个协程返回一个任务。
  2. 使用 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()
]))

2
你可以将协程列表传递给 asyncio.wait,无需在示例中使用 asyncio.ensure_future - Vincent
我该如何在此处添加额外的代码以在关闭连接后重新连接到WebSocket服务器? - user2455079

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接