如何在类中实现asyncio websockets?

时间:2016-05-22 02:05:11

标签: python python-3.x websocket python-3.5 python-asyncio

我想通过asynciowebsockets连接到websocket,格式如下所示。我怎么能做到这一点?

from websockets import connect


class EchoWebsocket:

    def __init__(self):
        self.websocket = self._connect()

    def _connect(self):
        return connect("wss://echo.websocket.org")

    def send(self, message):
        self.websocket.send(message)

    def receive(self):
        return self.websocket.recv()

echo = EchoWebsocket()
echo.send("Hello!")
print(echo.receive())  # "Hello!"

1 个答案:

答案 0 :(得分:21)

如何编写异步程序?

  1. 您应该使用async
  2. 定义异步功能
  3. 您应该调用异步 funcs与await
  4. 您需要event loop才能启动异步程序
  5. 所有其他几乎与常规Python程序相同。

    import asyncio
    from websockets import connect
    
    
    class EchoWebsocket:
        async def __aenter__(self):
            self._conn = connect("wss://echo.websocket.org")
            self.websocket = await self._conn.__aenter__()        
            return self
    
        async def __aexit__(self, *args, **kwargs):
            await self._conn.__aexit__(*args, **kwargs)
    
        async def send(self, message):
            await self.websocket.send(message)
    
        async def receive(self):
            return await self.websocket.recv()
    
    
    async def main():
        async with EchoWebsocket() as echo:
            await echo.send("Hello!")
            print(await echo.receive())  # "Hello!"
    
    
    if __name__ == '__main__':
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())
    

    输出:

    Hello!
    

    如您所见,代码与您编写的代码几乎相同。

    唯一的区别是websockets.connect被设计为异步上下文管理器(它使用__aenter____aexit__)。释放连接是必要的,并且还可以帮助您在类初始化期间进行异步操作(因为我们没有__init__的异步版本。)

    我建议你以同样的方式组织你的课程。但是如果你真的不想出于某些原因使用上下文管理器,你可以使用新的__await__方法进行异步初始化和其他一些异步函数来释放连接:

    import sys
    import asyncio
    from websockets import connect
    
    
    class EchoWebsocket:
        def __await__(self):
            # see: http://stackoverflow.com/a/33420721/1113207
            return self._async_init().__await__()
    
        async def _async_init(self):
            self._conn = connect("wss://echo.websocket.org")
            self.websocket = await self._conn.__aenter__()
            return self
    
        async def close(self):
            await self._conn.__aexit__(*sys.exc_info())
    
        async def send(self, message):
            await self.websocket.send(message)
    
        async def receive(self):
            return await self.websocket.recv()
    
    
    async def main():
        echo = await EchoWebsocket()
        try:
            await echo.send("Hello!")
            print(await echo.receive())  # "Hello!"
        finally:
            await echo.close()
    
    
    if __name__ == '__main__':
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())
    

    您可以在docs找到使用websockets的许多示例。