如何异步运行同一类的多个实例?

追求

我希望有许多代理连接到本地服务器的不同套接字,以便它们可以独立读取并发送到服务器。到目前为止,我有这个:

import json
import asyncio

class Agent():
    def __init__(self, user, pw):
        self.user = user
        self.pw = pw

        # Store host and port
        self.host, self.port = "localhost", 12300

        self.connect()

    async def connect(self):
        # Create asynchronous socket reader and writer
        self.reader, self.writer = await asyncio.open_connection(self.host,
                                                                 self.port)

        request = <some_json>

        # Create and send authentication request
        self.writer.write(request)
        await self.writer.drain()

        response = await self.reader.read(1000)
        response = json.loads(response.decode().split("\0")[0])

        if response["content"]["result"] == "ok":
            print("Connection Succesful")
        else:
            print("Connection Failed")

        await self.listen()

    async def receive_msg(self):
        """
        Waits for a message from the server and returns it.
        """
        msg = await self.reader.readuntil(b"\0")
        msg = msg.decode().split("\0")[0]

        # In case a message is received, parse it into a dictionary.
        if len(msg) > 1:

            return json.loads(msg)
        else:
            print("Retry receiving message...")
            return self.receive_msg()

    async def listen(self):
        """
        Listens for output from server and writes if anything is received
        """

        while True:
            msg = await self.receive_msg()
            print("Message received", self.user)


a_list = []

loop = asyncio.get_event_loop()

for i in range(15):
    a_list.append(Agent(f"agentA{i}", "1").connect())

loop.run_until_complete(asyncio.gather(*a_list))

由于异步的工作方式,我认为这是异步运行此方法的唯一方法。但是我希望能够以__init__某种方式异步运行,而不是connect如果可能的话,不必将函数放入循环中。我本质上想做的是:

a_list = []

loop = asyncio.get_event_loop()

for i in range(15):
    a_list.append(Agent(f"agentA{i}", "1"))

loop.run_until_complete(asyncio.gather(*a_list))

我认为这更有意义,但我不知道该怎么做。我是不是在想错了,还是有更好的方法来做到这一点?

用户名

您不能使__init__异步,但可以使Agent实例等待。为此,定义__await__魔术方法:

class Agent:
    def __init__(self, user, pw):
        self.user = user
        self.pw = pw
        self.host, self.port = "localhost", 12300

    def __await__(self):
        yield from self.connect().__await__()

这是两全其美的:您的__init__函数保持同步,而Agent实例是诸如之类的函数的有效参数asyncio.gather()

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章