Python WebSockets:如何使用异步调用覆盖同步方法WebSocketCommonProtocol.connection_made()?

时间:2018-08-10 04:05:09

标签: python websocket python-asyncio

当前WebSocketCommonProtocol.connection_made()被定义为同步呼叫。如果我想覆盖它并添加一些异步调用,似乎没有办法。

示例:我使用aioredis与Redis交谈;但是我在覆盖WebSocketCommonProtocol.connection_made()时不能使用aioredis。我能想到的唯一解决方法是在此函数中使用同步库redis-py,但在其他地方使用aioredis。它可以工作,但是非常难看。

asgiref.sync.async_to_sync()在这里不起作用:我已经在运行事件循环。此提交将阻止我使用它:https://github.com/django/asgiref/commit/9d42cb57129bd8d94a529a5c95dcf9f5d35a9beb

WebSocketCommonProtocol.connection_made()继承自asyncio.StreamReaderProtocol.connection_made()。因此,即使对于python标准库,这也是一个通用问题。不知道是否有人知道解决方案。

请给我一些解决此问题的建议。

1 个答案:

答案 0 :(得分:1)

制定一种解决方案:https://pypi.org/project/syncasync/

它将在新线程中运行异步代码。因此,它不会与同步代码发生竞争。这种方法非常慢:主线程将等待同步代码,而同步代码将等待新线程完成。

与其他解决方案相比:在程序中同时使用同步和异步库,该解决方案将允许您仅使用异步库。

尝试一下,让我知道所有错误,或提出更好的方法。

示例:

#!/usr/bin/env python

import asyncio

from syncasync import async_to_sync


class Base:
    def method(self):
        pass

    def run(self):
        self.method()


class Derived(Base):
    @async_to_sync
    async def method(self):
        await asyncio.sleep(0)


async def test():
    d = Derived()
    d.run()


if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(test())