如何在类中实现 asyncio websockets? [英] How can I implement asyncio websockets in a class?

查看:41
本文介绍了如何在类中实现 asyncio websockets?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过 asynciowebsockets 连接到 websocket,格式如下所示.我如何才能做到这一点?

I would like to connect to a websocket via asyncio and websockets, with a format as shown below. How would I be able to accomplish this?

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. 您应该使用 async
  2. 定义异步函数
  3. 你应该调用异步带有 await
  4. 的函数
  5. 您需要事件循环来启动您的异步程序立>
  1. You should define async funcs with async
  2. You should call async funcs with await
  3. You need event loop to start your async program

其他几乎与常规 Python 程序相同.

All other is almost same as with regular Python programs.

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!

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

As you see, code is almost same as you wrote.

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

Only difference is that websockets.connect designed to be async context manager (it uses __aenter__, __aexit__). It's necessary to release connection and will also help you to make async operations during class initialization (since we have no async version of __init__).

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

I advise you to organize your class same way. But if you really don't want to use context manager for some reason you can use new __await__ method to make async initialization and some other async function to release connection:

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 的示例.

Many examples of using websockets you can find in it's docs.

这篇关于如何在类中实现 asyncio websockets?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆