简体   繁体   中英

Python asyncio - starting coroutines in an infinite loop

I am making a simple server/client chat program in 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 .

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. However, the current code only starts accept_commands for the first connection, and blocks the while loop (the one in accept_new_connections ). Any idea what I need to change to have accept_command started for each of the connections instead?

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.

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. You can see this work concurrently by connecting two clients with netcat or telnet and sending data.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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