首页 文章

如何在data_received中更正asyncio yield

提问于
浏览
0

我会在data_received函数中向数据库发出异步请求,但我不知道怎么做 . 我用asyncio.sleep(2)编写了简单的HTTPServer,但它不起作用 .

import time
import asyncio

class HTTPServer:
    def connection_made(self, transport):
        self.transport = transport
        pass

    def connection_lost(self, exc):
        pass

    def eof_received(self):
        pass

    @asyncio.coroutine
    def data_received(self, data):
        try:
            #time.sleep(2)
            yield from asyncio.sleep(2)

            body = "Hello 
\n" response = 'HTTP/1.1 {status}\r\n'.format(status="200") response += 'Content-Length: {size}\r\n'.format(size=len(body)) response += 'Content-Type: text/html; charset=utf-8\r\n'.format(size=len(body)) response += 'Connection: close\r\n'.format(size=len(body)) response += '\r\n' response += body self.transport.write(response.encode('utf-8')) except e: print (e) self.transport.close() loop = asyncio.get_event_loop() print ('Start server on 0.0.0.0:8080') asyncio.ensure_future(loop.create_server( lambda: HTTPServer(), '0.0.0.0', 8080 )) try: loop.run_forever() pass except KeyboardInterrupt: loop.stop()

我评论了@ asyncio.coroutine行和从asyncio.sleep(2)得到的,它是有效的 . 我添加time.sleep(2)而不是asyncio.sleep(2),它的工作原理 . 但是异步不起作用 .

我究竟做错了什么?

1 回答

  • 2

    您正在使用的“协议”来自(引用文档):

    18.5.4 . 传输和协议(基于回调的API)

    正如文档中明确指出的那样,它会改变它,因此在"@asyncio.coroutine"中包装 data_received 将无法正常工作 .

    但是有一个基于协程的API,它是文档的下一章:

    18.5.5 . Streams(基于协程的API)

    使用基于协同程序的API重写您的示例,您将获得:

    import asyncio
    
    
    async def request_handler(reader, writer):
        await asyncio.sleep(2)
        data = await reader.read(100)
        message = data.decode()
        addr = writer.get_extra_info('peername')
        print("Received %r from %r" % (message, addr))
    
        body = "Hello 
    \n" response = 'HTTP/1.1 {status}\r\n'.format(status="200") response += 'Content-Length: {size}\r\n'.format(size=len(body)) response += 'Content-Type: text/html; charset=utf-8\r\n'.format(size=len(body)) response += 'Connection: close\r\n'.format(size=len(body)) response += '\r\n' response += body writer.write(response.encode('utf-8')) await writer.drain() writer.close() loop = asyncio.get_event_loop() coro = asyncio.start_server(request_handler, '127.0.0.1', 8080, loop=loop) server = loop.run_until_complete(coro) print('Start server on {}'.format(server.sockets[0].getsockname())) try: loop.run_forever() except KeyboardInterrupt: pass # Close the server server.close() loop.run_until_complete(server.wait_closed()) loop.close()

    请注意,如果您使用的是Python 3.5,则可以像我一样使用 async defawait 而不是 @asyncio.coroutineyield from .

相关问题