小编典典

具有异步计时器的Python异步Websocket客户端

python

我需要一个运行时间较长的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())

阅读 256

收藏
2021-01-20

共1个答案

小编典典

实际上,run_until_complete这里阻塞了,因为它一直等到alive完成。

您可以通过2个步骤解决它:

  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()
]))
2021-01-20