Python 官方文档:入门教程 => 点击学习
异步服务网关接口(Asynchronous Server Gateway Interface,ASGI)秉承WSGI统一网关接口原则,在异步服务、框架和应用之间提供一个标准接口,同时兼容WSGI。 01、ASGI ASGI是根据统一接口
异步服务网关接口(Asynchronous Server Gateway Interface,ASGI)秉承WSGI统一网关接口原则,在异步服务、框架和应用之间提供一个标准接口,同时兼容WSGI。
ASGI是根据统一接口的思想重新设计的新标准,你可能会有疑问,为什么不直接升级WSGI而去创造新的标准呢?
WSGI是基于Http短连接的网关接口,一次调用请求必须尽快处理完毕并返回结果,这种模式并不适用于长连接,例如html 5新标准中的技术SSE(Server-Sent Events)和websocket,WSGI及传统阻塞型io 编程模型并不擅长处理这类请求。就算强行升级WSGI以支持异步IO,可是如果配套的技术(如Apache服务器)没有提供相应的支持也是没有意义的。既然python异步IO 编程模型已经走在了前面,那就制定一个全新的标准ASGI以最优雅的方式支持并使用最新的技术。
ASGI接口是一个异步函数,它要求传入3个参数,分别为 scope、receive和send,示例代码如下:
async def app(scope, receive, send): pass
其中scope是一个字典(dict),包括连接相关的信息,图1所示是一个请求中的scope所包括信息的断点调试截图。
receive是一个异步函数,用于读取前端发来的信息,一条读取到的信息结构如下:
{ 'type':'http.request', 'body':b"", 'more_body':False}
该信息中包括3个字段,分别为类型(type)、内容(body)和是否还有更多内容(more_body),其中通过type 可以用来判断该信息是什么类型,如HTTP 请求、生命周期、WEBSocket请求等,body是该信息中包括的数据,此数据采用二进制格式,more_body指明当前数据是否已经发送完毕,如果发送完毕,则more_body的值为False,这样便可以用来分段传输大文件。
■ 图1 断点截图
send也是一个异步函数,用于向前端发送信息,所发送的信息结构与从前端接收的信息结构类似。一个向前端发送简单信息的示例代码如下:
async def app(scope, receive, send):#向前端发送HTTP协议头,包括了HTTP状态与协议头 await send({ 'type':'http.response.start', 'status':200, 'headers':[ [b'content-type', b'text/html'], ] })#向前端发送数据,如果数据庞大,还可以分段发送 await send({ 'type':'http.response.body', 'body':b"Hello World", 'more_body':False })
除了常规数据通信外,ASGI 还规定了生命周期管理接口,可以用于侦听服务器的启动与关闭。在实际开发工作中,这非常有用,可以用来执行初始化工作与收尾工作,生命周期管理的运用代码如下:
async def app(scope, receive, send): request_type = scope['type'] if request_type == 'lifespan': while True: message = await receive() if message['type'] == 'lifespan.startup': await send({'type':'lifespan.startup.complete'}) elif message['type'] == 'lifespan.shutdown': await send({'type':'lifespan.shutdown.complete'}) break
当scpoe['type']的类型是lifespan时,意味着该请求的类型是生命周期,该请求会在服务器启动之初发生,接下来应该实现对生命周期的管理。
通过无限循环不断侦听请求状态的变化,当读到message[t' ype']是lifespan.startup时执行初始化操作,在操作完成后向前端(协议层)发送lifespan.startup.complete信息,协议层可理解为服务器已经启动完成,可以正常接受浏览器请求了。
当读到message['type']是lifespan.shutdown时,意味服务要关闭,可能是由于服务器管理员执行了关闭指令,那么在这里就需要执行收尾工作,例如释放相应资源等。在收尾完成后向协议层发送lifespan.shutdown.complete信息,表明此时协议层可以放心地关闭服务器。
一个完整的基于ASGI的 Hello World 示例代码如下:
async def app(scope, receive, send): request_type = scope['type'] if request_type == 'http': await send({ 'type':'http.response.start', 'status':200, 'headers':[ [b'content-type', b'text/html'], ] }) await send({ 'type':'http.response.body', 'body':b"Hello World", 'more_body':False }) elif request_type == 'lifespan': while True: message = await receive() if message['type'] == 'lifespan.startup': await send({'type':'lifespan.startup.complete'}) elif message['type'] == 'lifespan.shutdown': await send({'type':'lifespan.shutdown.complete'}) break else: raise NotImplementedError()
Uvicorn是ASGI的一个协议层实现,一个轻量级的ASGI服务器,基于uvloop 和httptools实现,运行速度极快。
uvloop是一个高效的基于异步IO 的事件循环框架,底层实现由libuv承载。libuv是一个使用C语言开发的支持高并发的异步IO 库,由node.js的作者开发,作为node.js的底层IO 库实现,如今已经发展得相当成熟稳定。
要使用Uvicorn需要先通过命令pip install uvicorn安装该依赖项,项目结构如图2所示。
接下来在终端输入uvicorn asgi:app以启动该服务器,效果如图3所示
■ 图2 ASGI项目文件结构
■ 图3 启动ASGI服务器
服务器启动后,可使用浏览器通过http://127.0.0.1:8000访问该站点,结果如图4所示。
为了向用户提供更加安全的服务,现代网站都需要支持https,Uvicorn 也提供了对HTTPS的支持,使用起来也相当方便。
首先准备好HTTPS证书文件,如图5所示。
■图4 页面访问结果
■ 图5 证书文件所在目录
接下来通过命令uvicorn--ssl-certfile ./ssl/cert.pem--ssl-keyfile ./ssl/cert.key asgi:app来启动该服务器,如图6所示。
■ 图6 以HTTPS方式启动服务器
FROM Python:3-slimRUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple uvicorn
容器化对应的docker-compose.yml内容如下:
services: web: build:. restart:always tty:true ports: - "8000:8000" volumes: - ".:/opt/" working_dir:"/opt/" command:uvicorn --host 0.0.0.0 asgi:app
03、源码
来源地址:https://blog.csdn.net/qq_41640218/article/details/132014936
--结束END--
本文标题: Python异步编程|ASGI 与 Django(附源码)
本文链接: https://lsjlt.com/news/386117.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0