This is similar to Calling coroutines in asyncio.Protocol.data_received but I think it warrants a new question.
I have a simple server set up like this
You need to add your coroutine to the event loop, and then use Future.add_done_callback to handle the result when the coroutine completes:
@asyncio.coroutine
def go(self):
return(yield from asyncio.sleep(3, result = b'data reply'))
def data_received(self, data):
print('Data Received', flush=True)
task = asyncio.async(self.go()) # or asyncio.get_event_loop().create_task()
task.add_done_callback(self.handle_go_result)
def handle_go_result(self, task):
data = task.result()
self.send(data)
Calling a coroutine directly in data_received
just simply isn't allowed, since the caller isn't going to try to yield from
it, and creating/running a new event loop inside of data_received
will always end up blocking the main event loop until the inner event loop finishes its work.
You just want to schedule some work with your main event loop (asyncio.async
/loop.create_task()
), and schedule a callback to run when the work is done (add_done_callback
).