aiohttp

輕舟輕發表於2016-12-07

asyncio是Python 3.4版本引入的標準庫,直接內建了對非同步IO的支援。

asyncio的程式設計模型就是一個訊息迴圈。

asyncio提供了完善的非同步IO支援;

非同步操作需要在coroutine中通過yield from完成;

多個coroutine可以封裝成一組Task然後併發執行。

asyncio可以實現單執行緒併發IO操作。如果僅用在客戶端,發揮的威力不大。如果把asyncio用在伺服器端,例如Web伺服器,由於HTTP連線就是IO操作,因此可以用單執行緒+coroutine實現多使用者的高併發支援。

asyncio實現了TCP、UDP、SSL等協議,aiohttp則是基於asyncio實現的HTTP框架。

我們先安裝aiohttp:

pip install aiohttp
然後編寫一個HTTP伺服器,分別處理以下URL:

  1. / - 首頁返回b'<h1>Index</h1>'
  2. /hello/{name} - 根據URL引數返回文字hello, %s!。 

程式碼如下:

#!/usr/bin/env python3
#-*- coding: utf-8 -*-

import asyncio, os, json, time
from datetime import datetime
from aiohttp import web

#!/usr/bin/env python3
#-*- coding: utf-8 -*-

import logging
#設定日誌等級,預設是WARNING.只有指定級別或更高階的才會被追蹤記錄
logging.basicConfig(level=logging.INFO)
import asyncio, os, json, time
from datetime import datetime
from aiohttp import web

def index(request):
    #返回web的請求
    return web.Response(body=b'<h1>Awesome</h1>', content_type='text/html', charset='UTF-8')

async def init(loop):
    #建立web應用    建立一個迴圈型別是訊息迴圈的web應用物件
    app = web.Application(loop=loop)
    app.router.add_route('GET', '/', index)
    #呼叫子協程:建立一個TCP伺服器,繫結到“0.0.0.0:9000”socket,並返回一個伺服器物件
    srv = await loop.create_server(app.make_handler(),'0.0.0.0', 9000)
    logging.info('server started at http://0.0.0.0:9000...')
    return srv

loop = asyncio.get_event_loop()         #loop收一個訊息迴圈
loop.run_until_complete(init(loop))     #在訊息迴圈中執行協程
loop.run_forever()


注意aiohttp的初始化函式init()也是一個coroutine,loop.create_server()則利用asyncio建立TCP服務。