简体   繁体   English

Python asyncio - 在无限循环中启动协程

[英]Python asyncio - starting coroutines in an infinite loop

I am making a simple server/client chat program in Python.我正在用 Python 制作一个简单的服务器/客户端聊天程序。 This program should allow for multiple users to connect at once, and then execute their requests concurrently.该程序应该允许多个用户同时连接,然后并发执行他们的请求。 For this, I am using the asyncio module and sockets .为此,我使用了asyncio模块和sockets

async def accept_new_connections(socket):
    socket.listen(1)
    while True:
        connection, client_address = sock.accept()
        print("accepted conn")
        asyncio.create_task(accept_commands(socket, connection))

async def accept_commands(socket, connection):
    print("accept cmd started")
    while True:
        # get and execute commands

def main():
    asyncio.run(accept_new_connections(socket))

main()

What I would hope to do is running accept_commands for each of the connections, which would then execute commands concurrently.我希望做的是为每个连接运行accept_commands ,然后并发执行命令。 However, the current code only starts accept_commands for the first connection, and blocks the while loop (the one in accept_new_connections ).但是,当前代码只为第一个连接启动accept_commands ,并阻塞 while 循环( accept_new_connections中的accept_new_connections )。 Any idea what I need to change to have accept_command started for each of the connections instead?知道我需要更改什么才能为每个连接启动accept_command吗?

It is tough to tell because your example does have the implementation of accept_commands , but based on your issue it is likely you need to use the async socket methods on event loop itself so that your coroutine can yield execution and let something else happen.很难说,因为您的示例确实实现了accept_commands ,但根据您的问题,您可能需要在事件循环本身上使用异步套接字方法,以便您的协程可以执行并让其他事情发生。

The below example shows how to do this.下面的例子展示了如何做到这一点。 This starts a socket on port 8080 and will send back any data it receives back to the client.这会在端口 8080 上启动一个套接字,并将它接收到的任何数据发送回客户端。 You can see this work concurrently by connecting two clients with netcat or telnet and sending data.您可以通过使用netcattelnet连接两个客户端并发送数据来同时查看此工作。

import asyncio
import socket

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

socket.bind(('localhost', 8080))
socket.listen(1)
socket.setblocking(False)
loop = asyncio.new_event_loop()

async def main():
    while True:
        connection, client_address = await loop.sock_accept(socket)
        print('connected')
        loop.create_task(accept_commands(connection))


async def accept_commands(connection):
    while True:
        request = await loop.sock_recv(connection, 16)
        await loop.sock_sendall(connection, request)


loop.run_until_complete(main())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM