ASGI是什么?

347 阅读2分钟

上一篇文章(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的实际使用。