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

问题描述 投票:0回答:1

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

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))

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

python asynchronous python-asyncio
1个回答
0
投票

您无法使__init__异步,但是can使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()之类的函数的有效参数。

© www.soinside.com 2019 - 2024. All rights reserved.