Hi, On 18 July 2014 09:47, yi huang <[email protected]> wrote:
> The example in asyncio documentation only shows how to write echo server > in twisted style, and i wonder how can i write server handler as a > coroutine like in gevent, something like: > > def handle_client(transport): > while True: > buf = yield from transport.read(4096) > # handle request > > # read some result from database without blocking other coroutine. > result = yield from block_read_from_database() > > loop.create_server(handle_client, '127.0.0.1', 3000) > > You cannot use coroutines in asyncio callbacks. If you want to use a coroutine to handle the server response, it must be wrapped via the *asyncio.async* function. This is a common mistake, possibly because documentation is a little scarce on this crucial point https://docs.python.org/3/library/asyncio-task.html#asyncio.async In addition * the *create_server* method returns a coroutine, so it must be wrapped * the *protocol_factory* must be a callable - called without arguments and must return a protocol instance (this point is not clear in the docs) https://docs.python.org/3/library/asyncio-eventloop.html#creating-listening-connections but it is stated in https://docs.python.org/3/library/asyncio-eventloop.html#creating-connections Your example could look like: import asyncio def block_read_from_database(): result = yield from asyncio.sleep(1, b'OK') return result class Protocol(asyncio.Protocol): def connection_made(self, transport): self._transport = transport def data_received(self, data): asyncio.async(self.response(data)) def response(self, data): '''This is the coroutine which handle the response ''' result = yield from block_read_from_database() self._transport.write(result) loop = asyncio.get_event_loop() asyncio.async(loop.create_server(Protocol, '127.0.0.1', 3000), loop=loop) loop.run_forever() -- http://lucasbardella.com
