python-3.x - aiohttp 和 asyncio 如何以并发方式从 http 请求和 websocket 获得响应?
问题描述
我尝试同时从两个端点接收数据。但是,如果 websocket 停止发送消息,我将不会收到来自"https://www.blabla.com"
. 解决这个问题的最佳方法是什么?
import asyncio
import aiohttp
URL = 'wss://www.some_web_socket.io'
async def get_some_data(session):
url = "https://www.blabla.com"
async with session.get(url) as response:
data = await response.text()
return data
async def ws_handler(url):
async with aiohttp.ClientSession() as session:
async with session.ws_connect(url) as ws:
msg = await ws.receive()
while True:
some_data_from_get_request = await get_some_data(session)
msg_from_websocket = await ws.receive()
if msg.type == aiohttp.WSMsgType.TEXT:
print(stream_data)
print(some_data_from_get_request)
def _main():
asyncio.run(ws_handler(URL))
if __name__ == "__main__":
_main()
解决方案
这段代码序列化了 HTTP 和 websocket 通信的返回值:
while True:
some_data_from_get_request = await get_some_data(session)
msg_from_websocket = await ws.receive()
为了能够检测到返回的两个协程中的任何一个,您可以使用asyncio.wait(..., return_when=asyncio.FIRST_COMPLETED)
:
http_fut = asyncio.ensure_future(get_some_data(session))
ws_fut = asyncio.ensure_future(ws.receive())
pending = {http_fut, ws_fut}
while pending:
_done, pending = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED)
if http_fut.done():
some_data_from_get_request = http_fut.result()
...
if ws_fut.done():
msg_from_websocket = ws_fut.result()
...
推荐阅读
- docker - dockerfile getaddrinfo 失败:名称或服务未知
- python - 使用 optuna 优化时的 TensorFlow / keras 问题
- node.js - 错误:找不到模块 'src/utils/email/sendEmail',绝对导入在 Node.js/Typescript 中不起作用
- javascript - 如何在警报中显示错误消息而不是在 AspNet MVC 中的跨度类
- linux - 如何在 Linux 服务器上运行 Kettle Job - Pentaho 数据集成
- javascript - JS 中的 SoapClient
- python - 比较两个数据框列以匹配字符串或者是子字符串然后在熊猫中计数(需要快速版)
- qt - QML 图层元素在重叠时“显示”其上方的元素
- mysql - 第 12 行的错误 1045 (28000):用户 'aviswanathan'@'%' 的访问被拒绝(使用密码:是)
- batch-file - 将所有文件从一个文件夹复制到具有模式匹配的目标文件夹名称