aiohttp и asyncio, как получить ответ от http-запроса и websocket одновременно? - PullRequest
0 голосов
/ 19 января 2019

Я пытаюсь получать данные с двух конечных точек одновременно.Но если 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()

1 Ответ

0 голосов
/ 19 января 2019

Этот код сериализует возвращаемые значения HTTP и связи через веб-сокет:

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 = 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()
        ...
...