我会在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 <br/>\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),它的工作原理。但异步不起作用。
我做错了什么?
答案 0 :(得分:2)
您使用的“协议”来自(引用文档):
18.5.4。传输和协议(基于回调的API)
正如文档中明确指出的那样,它是一个“基于回调的API”,它调用普通方法,你无法改变它,因此将data_received
包装在“@ asyncio.coroutine”中是行不通的
但是有一个基于协程的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 <br/>\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 def
和await
代替@asyncio.coroutine
和yield from
。