在 asyncio 服务器启动后执行协程

Execute a coroutine after asyncio server is started

我正在开发一个控制器应用程序,它监视和控制独立的 python 可执行文件的子进程。 基本上我想要的是 controller.py 运行 中的 asyncio.star_server。服务器启动后 运行 controller.py 应该作为连接到它的客户端执行其他 python 文件。控制器服务器永远运行并创建新的客户端实例,并在必要时向它们发送关闭消息。

不幸的是,这不起作用。没有收到错误,只是挂起。

controller.py:


async def handleClient(reader, writer):
    #handling a connection
    addr = writer.get_extra_info("peername")
    print(f"connection from {addr}")

    data_ = await reader.readline()
    ...

async def startClient(client_py_file, host, port):
    # this executes another py file that will connect to this server
    await asyncio.sleep(0.1)
    subprocess.run(["python.exe", client_py_file, host, port])

async def main():
    server = await asyncio.start_server(handleClient, "127.0.0.1", 4000)
    await asyncio.ensure_future(startClient("client.py", "127.0.0.1", 4000)
    await server.wait_closed()

asyncio.run(main())

它似乎执行了 client.py 启动,连接到服务器没有任何错误。

client.py:

async def async_client(loop):
    reader, writer = await asyncio.open_connection(host, port, loop = loop)
    writer.writelines([json.dumps("key" : idstr, "msg" : "this is my message"}, b"\n"])
    await writer.drain()
    while True:
        data = await reader.readline()
        ....

现在客户端挂起并等待服务器的响应。但是在服务器上,不会触发 handleClient 处理程序。不知道出了什么问题。请你帮助我好吗? 提前致谢!

问题是subprocess.run是一个阻塞函数,等待客户端完成。在此等待期间,事件循环被阻塞,无法为传入连接提供服务。

最简单的修复方法是将 subprocess.run(...) 替换为 subprocess.Popen(...),这会做同样的事情,但不等待子进程完成就返回一个句柄。如果你需要和子进程通信,你也可以使用asyncio.create_subprocess_exec(...),它也是returns一个句柄,但是像wait()这样的方法是协程。