如何在类中实现asyncio websockets?

2Cu*_*bed 19 python websocket python-3.x python-asyncio python-3.5

我想通过asyncio和连接到websocket websockets,格式如下所示.我怎么能做到这一点?

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!"
Run Code Online (Sandbox Code Playgroud)

Mik*_*mov 25

如何编写异步程序?

  1. 你应该定义async funcs async
  2. 你应该调用async funcs await
  3. 您需要事件循环来启动异步程序

所有其他几乎与常规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())
Run Code Online (Sandbox Code Playgroud)

输出:

Hello!
Run Code Online (Sandbox Code Playgroud)

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

唯一的区别是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())
Run Code Online (Sandbox Code Playgroud)

许多使用websockets你的例子可以在它的文档中找到.