使用同步API包装websockets asyncio

时间:2018-10-08 07:02:22

标签: python python-asyncio

我正在使用python websockets library来创建websocket服务器。我的目标是导出同步 API,因为它将在python之外使用。

因此,至少在开始时,我需要start()stop()方法。因此,为此创建一个websocket服务器类似乎是正确的。
主要问题在于,通过库创建(和启动)服务器的方式是通过await实现的,因此应鼓励将这些方法设置为async,这是我尽量避免的方法。

当我运行main()函数时,以下代码可以完美运行。
当运行server = WebsocketServer(); server.start(1234)ipython shell时,我似乎无法通过客户端代码进行连接。我想念什么?

class WebsocketServer():

    def __init__(self):
        self._server = None

    def start(self, port):
        start_server = websockets.serve(self._handle_client,
                                        host='localhost',
                                        port=port)
        self._server = asyncio.get_event_loop().run_until_complete(start_server)

    def stop(self):
        if self._server:
            self._server.close()
            self._server = None

    async def _handle_client(self, client, path):
        async for buffer in client:
            await self._handle_buffer(client, buffer)

    async def _handle_buffer(self, client, buffer):
        print(buffer)
        await client.send(buffer)

def main():
    server = WebsocketServer()
    server.start(1234)
    asyncio.get_event_loop().run_forever()

2 个答案:

答案 0 :(得分:0)

通过tasks进入IO循环的同步接口。调度方法返回的将来可以根据需要同步等待。文档的run an event loop部分的底部有一个用于同步关机的组合。

在iPython Shell中运行时,一种选择是为IO循环生成守护进程后台线程,并注册atexit回调以在Shell退出时同步关闭IO循环。

另一种选择是使用here描述的UI事件循环集成点描述如何借用外壳线程来偶尔借用外壳线程来执行IO任务(仅适用于短期任务,原因)。用于IO。

答案 1 :(得分:0)

您缺少主函数的最后一行。

asyncio.get_event_loop().run_forever()

当循环没有运行时什么也不会发生。因此,除非您运行循环,否则服务器不会运行。