【问题标题】:Execute a coroutine after asyncio server is started在异步服务器启动后执行协程
【发布时间】:2020-08-01 09:40:13
【问题描述】:

我正在开发一个控制器应用程序,该应用程序监视和控制作为独立 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 处理程序没有被触发。不知道出了什么问题。请你帮助我好吗? 提前谢谢!

【问题讨论】:

    标签: python asynchronous subprocess python-asyncio


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢! Popen 解决了阻塞问题。是的,我需要沟通。同时我提出了一个单独的问题:link。请注意,每个工作人员都必须与控制器通信,并且还必须通过数据流相互通信。因此,带有 stdin/stdout 的子进程可能不是最适合该问题的。仍在研究和学习 :-) 非常欢迎任何建议!
    猜你喜欢
    • 2018-02-24
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 2013-02-26
    • 1970-01-01
    • 2018-02-10
    相关资源
    最近更新 更多