上一篇文章(juejin.cn/post/731003…) 讨论了WSGI的内容,由于时代的发展,WEB发展迅速,传统的WSGI协议,已经不能够满足websocket等需求。同时,WSGI协议不支持异步请求,每一个请求过来,需要开启新的线程去处理。python对异步的支持也越来越好,现在需要一个新的协议来解决新的需求。
ASGI是由Django社区提出的。这是ASGI文档
通过文档可以看出,ASGI是WSGI的一种补充。
符合ASGI协议的接口
这边不阐述ASGI在web服务器和web应用中的作用,它和WSGI作用是一样的,充当“桥梁”。
直接看一下符合ASGI协议的接口长什么样:
async def app(scope, receive, send):
assert scope['type'] == 'http'
# data = await receive()
# print(data)
message = "Hello, World!"
await send({
'type': 'http.response.start',
'status': 200,
'headers': [
[b'content-type', b'text/plain'],
],
})
await send({
'type': 'http.response.body',
'body': message.encode('utf-8'),
})
和WSGI是很相似的,ASGI协议要求一个异步的可调用对象,接收三个参数:
scope:包含了请求头信息:
{'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, .... 'state': {}}
其中的type显示请求的类型,是http还是websocket
receive:是一个异步可调用对象,用来接收客户端的数据
send:是一个异步可调用对象,用来发送响应。可以看到send可以多次发送,上面的例子,第一次发送响应头,第二次发送响应体。
在介绍WSGI的时候说过,实现这个协议的可调用对象需要一个web服务器启动,如Flask里面的app.run(),以及python内置的make_server。与之类似的,ASGI也有响应的web服务器。这边使用uvicorn
安装:pip install uvicorn
启动:
async def app(scope, receive, send):
assert scope['type'] == 'http'
# data = await receive()
# print(data)
message = "Hello, World!"
# 发送响应给客户端
await send({
'type': 'http.response.start',
'status': 200,
'headers': [
[b'content-type', b'text/plain'],
],
})
await send({
'type': 'http.response.body',
'body': message.encode('utf-8'),
})
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
这两篇简单介绍一下WSGI和ASGI的内容,后续会结合几个框架的源码,再深入地探讨WSGI和ASGI的实际使用。