I keep getting the error cannot call recv() while another coroutine is already waiting for the next message

Viewed 3125

When I run my paddleLogic function twice I get the error "cannot call recv() while another coroutine is already waiting for the next message" Even though I am using await to ensure that they are not trying to receive at the same time.

I have run the code without calling the paddleLogic function the second time, and everything works as expected

    leftPaddlePos = await paddleLogic(websocket,leftPaddlePos)
    rightPaddlePos = await paddleLogic(opponent[websocket],rightPaddlePos)

async def paddleLogic(socket,pos):
        try:
            key = await asyncio.wait_for(socket.recv(),timeout=0.01)
            if key == "1" and pos > 0:
                pos = pos - 1
            elif key == "2" and pos < 60:
                pos = pos + 1
            time.sleep(0.003)
        except asyncio.TimeoutError:
            pos = pos
        return pos

Sorry if this post is kind of a mess, this is my first time asking a question on stackoverflow. If you want more information/code I'm happy to provide it.

1 Answers

Where do you get your sockets?

What we have is coroutines. They are scheduled by them yielding control to one another. They yield control when they call await. It appears that your socket.recv also does some waiting behind the scenes by yielding control, so recv is entered twice if data from network are not immediately available.

I suppose that you'd be better off accessing asyncio event loop socket support. Otherwise, I'd use select() to look at both sockets in parallel, returned events like ('left paddle', -1) from my async generator, and updated the game world accordingly.

(I can even suppose that a real-time game like pong would be easier to implement in a completely synchronous way, paced by frame rate.)

Related