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

Reply via email to