当前位置: 首页 > 知识库问答 >
问题:

带有异步计时器的Python异步websocket客户端

汪弘光
2023-03-14

我需要有一个长时间运行的websocket客户端,它接收来自websocket服务器的推送消息,并且我需要监视客户端的连接状态:如果连接中断,我需要发现。

我的方法是定期记录一个常量字符串,如果没有检测到日志消息,就触发警报。

我的想法是:1)有一个websocket客户机来响应不定期传入的消息。2)同时有一个循环,当websocket客户机抛出一个ConnectionClosed exeption时停止记录消息。

我对新的3.5异步语法很感兴趣。这个websocket实现是专门基于Asyncio的。文件里的客户和我需要的一模一样。

但是,我不知道如何添加第二个coroutine来执行日志记录语句,并在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个答案

邓俊英
2023-03-14

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

你可以用2步来解决:

  1. 调度与asyncio.ensure_future(立即运行而不等待结果)对应,每个返回任务。
  2. 使用Asyncio.wait
  3. 等待任务完成
tasks = [
   asyncio.ensure_future(alive()),
   asyncio.ensure_future(async_processing())
]
asyncio.get_event_loop().run_until_complete(asyncio.wait(tasks))
asyncio.get_event_loop().run_until_complete(asyncio.wait([   
   alive(),
   async_processing()
]))
 类似资料:
  • C Async描述了如何创建一个异步服务器和一个相应的异步客户机来与之通信。我已经在微软ViualStudio中创建了这个。 我现在需要一个java客户端说话的C服务器-我无法找到一个Java等效的客户端(到C)与C通信。 任何指点都将不胜感激

  • 异步Mysql客户端 AsyncMysql::query($sql, $usePool = true) 第二个参数设为false将不会使用连接池中的资源,默认都会从连接池中取,配置连接池数量 => config/database.php 具体使用 use AsyncMysql; //设置超时时间 AsyncMysql::setTimeout(2); $res = (

  • 异步Redis客户端 连接池(连接池默认开启) use AsyncRedis; //关闭连接池 AsyncRedis::enablePool(false); //开启连接池 AsyncRedis::enablePool(true); 使用AsyncRedis use AsyncRedis; //设置超时时间 AsyncRedis::s

  • 异步Http客户端 Get方式 1.使用域名形式 use AsyncHttp; //直接使用域名, get方式 $http = new AsyncHttp('http://groupco.com'); //设置2s超时 $http->setTimeout(2); //$http->setCookies(['token' => 'xxxx']);

  • 异步Tcp客户端 串行发包 use AsyncTcp; $tcp = new AsyncTcp('127.0.0.1', 9501); $tcp->setTimeout(2); //串行发送 $res = (yield $tcp->call('hello server!')); $res = (yield $tcp->call('hello serv

  • 我正在使用Android异步Http客户端。我的代码看起来像这样,并且运行良好。 我实现了一个静态HTTP客户端。我的服务器返回这个JSON数据。我不想将其视为字符串并将其转换回JSON。但是当我将其更改为eclipse告诉我 new AsyncHttpResponseHandler(){}类型的onSuccess(JSONObject)方法必须重写或实现超类型方法