(技术)Python 3 -- 异步IO: aiohttp
2017-11-25 本文已影响0人
点映文艺
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging;logging.basicConfig(level=logging.INFO)
import asyncio
from aiohttp import web
'''
python 3.5版本: async 表示把generator(生成器home)标记为coroutine(协程)类型;
await asyncio.sleep(0.5) 表示用await调用coroutine(协程)实现异步操作
python 3.5之前版本等价写法:@asyncio.coroutine 把generator标记为coroutine类型; await等价于 yield from
request 为aiohttp.web.request实例,包含了所有浏览器发送过来的HTTP协议里面的信息
'''
async def home(request):
# 在coroutine(协程)内部用await(或yield from)调用另一个coroutine(协程)实现异步操作,asyncio.sleep(0.5)看成是一个耗时1秒的IO操作
await asyncio.sleep(0.5)
# web.Response()为aiohttp.web.response实例,由web.Response(body='')构造,继承自StreamResponse,功能为构造一个HTTP响应
# 类声明 class aiohttp.web.Response(*, status=200, headers=None, content_type=None, body=None, text=None)
return web.Response(body='This is home page.')
# async 表示把generator标记为coroutine(协程)类型
# request 为aiohttp.web.request实例,包含了所有浏览器发送过来的HTTP协议里面的信息
async def greeting(request):
await asyncio.sleep(0.5)
return web.Response(body=' Hi,%s! '% request.match_info['name']) # body=text.encode('utf-8')
#async 表示把generator标记为coroutine(协程)类型
async def init_server(loop):
'''
创建Web服务器实例app,即aiohttp.web.Application类的实例,该实例的作用是处理URL、HTTP协议
Application构造函数 def __init__(self, *, logger=web_logger, loop=None,
router=None, handler_factory=RequestHandlerFactory,
middlewares=(), debug=False):
'''
app = web.Application(loop = loop)
'''
注册URLs到router,router默认为UrlDispatcher实例,add_route(method, path, handler, *, name=None, expect_handler=None)
add_route方法将处理函数(参数名为handler)与对应的URL绑定,浏览器输入URL时返回处理函数内容
'''
app.router.add_route('GET','/',home)
app.router.add_route('GET','/greet/{name}',greeting)
'''
用coroutine(协程)创建监听服务,其中loop为传入函数的协程,调用其类方法创建一个监听服务,声明如下
coroutine BaseEventLoop.create_server(protocol_factory, host=None,
port=None, *, family=socket.AF_UNSPEC,
flags=socket.AI_PASSIVE, sock=None, backlog=100,
ssl=None, reuse_address=None, reuse_port=None)
并使用aiohttp中的HTTP协议簇(protocol_factory)
await 返回一个创建好的绑定IP、端口、HTTP协议簇监听服务的coroutine(协程),
await的作用是使server的行为模式和loop.create_server()一致
loop.create_server() 利用asyncio创建TCP服务,make_handler()创建aiohttp.RequestHandlerFactory,用来处理HTTP协议
'''
server = await loop.create_server(app.make_handler(),'127.0.0.1',8000)
logging.info('Server started at http://127.0.0.1:8000')
return server
# 从asyncio中获取EventLoop引用,为asyncio.BaseEventLoop的对象
# 注意:变量名必须叫loop,否则 TypeError: __init__() got an unexpected keyword argument 'my_event_loop',不明白为啥?
loop = asyncio.get_event_loop();
# 运行协程,直到完成,BaseEventLoop.run_until_complete(future)
loop.run_until_complete(init_server(loop))
# 运行协程,直到调用 stop(), BaseEventLoop.run_forever()
loop.run_forever();