【问题标题】:Websocket subscriptions and co-routines: Extracting message without exiting loop?Websocket订阅和协同程序:在不退出循环的情况下提取消息?
【发布时间】:2020-03-12 09:43:36
【问题描述】:

我正在尝试组织我对 API 的实时订阅,这是我目前所拥有的:

async def real_time_info():
    channels = ['channel1']
    msg_subscription = msg.public_subscribe(channels)
    async with websockets.connect(URL) as websocket:
        await websocket.send(json.dumps(msg_subscription))
        while websocket.open:
            subscription = json.loads(await websocket.recv())
            return subscription #HERE IS THE PROBLEM I'M TRYING TO SOLVE


async def real_time_data():
    channels = ['channel2']
    msg_subscription = msg.public_subscribe(channels)
    async with websockets.connect(URL) as websocket:
        await websocket.send(json.dumps(msg_subscription))
        while websocket.open:
            subscription = json.loads(await websocket.recv())
            return subscription #HERE IS THE PROBLEM I'M TRYING TO SOLVE


async def main():
    info = asyncio.create_task(real_time_info())
    data = asyncio.create_task(real_time_data())

    while True:
        print(await info)
        print(await data)

asyncio.run(main())

所以我想做的是每次有来自real_time_info()real_time_data()的消息,打印出来。问题是因为我使用 return 它会自动退出该函数,当然也会停止从 websocket 获取消息。

从技术上讲,我可以通过将所有内容放在一个函数中并在其中完成所有内容而不需要退出 for 循环来做到这一点,但是这样一来一团糟,而且真的很难管理我从中获取的消息插座。

有没有办法将我的real_time 函数中的这些套接字消息转移到 main,同时它们仍在循环中运行?

谢谢!

编辑:我还会问另一个关于 websockets 的问题,这些问题可能会使这一切变得微不足道。现在我通过 2 个不同的函数连接到同一个 API 的 2 个通道(channel1 和 channel2)。但是因为在他们两个中我都尝试通过await websocket.recv()从服务器读取消息,这些消息是否仍然混合在同一个“接收者”中?如果是这样,有没有办法通过 websockets 管理来自服务器的响应?再次感谢。

【问题讨论】:

    标签: python websocket python-asyncio


    【解决方案1】:

    asyncio.Queue() 的实例传递给您的异步函数,并将return subscription 替换为await queue.put(('channel1', subscription))。那么你的main 可以是这样的:

    async def main():
        queue = asyncio.Queue()
        info = asyncio.create_task(quote_info(queue))
        data = asyncio.create_task(trades_info(queue))
    
        while True:
            channel, subscription = await queue.get()
            print(channel, subscription)
    

    【讨论】:

    • 谢谢!我对 asyncio 很陌生,所以不知道 Queue 方法。您知道创建 2 个单独的订阅但使用相同的接收者 websocket.recv() 是否有助于管理消息?或者因为它只是一个池,我可以在一个功能中同时拥有两个通道而没有区别? (请参阅我在 OP 中的编辑) P.S.:我在 OP 中编辑了 quote_infotrade_info 名称,因为我一开始就忘了这样做,可能会引起一些混乱。
    • @Hiperfly 老实说,我不知道 websocket 特定问题的答案。
    猜你喜欢
    • 2016-10-27
    • 2022-10-15
    • 2014-09-07
    • 1970-01-01
    • 2020-04-28
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多