我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python异步编程|ASGI 与 Django(附源码)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python异步编程|ASGI 与 Django(附源码)

图片

异步服务网关接口(Asynchronous Server Gateway Interface,ASGI)秉承WSGI统一网关接口原则,在异步服务、框架和应用之间提供一个标准接口,同时兼容WSGI。

01、ASGI

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()

02、Uvicorn

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方式启动服务器

容器化对应的 Dockerfile 文件内容如下:

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

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python异步编程|ASGI 与 Django(附源码)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

fastapi与django异步的并发源码对比分析

这篇文章主要介绍“fastapi与django异步的并发源码对比分析”,在日常操作中,相信很多人在fastapi与django异步的并发源码对比分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”fastapi
2023-07-05

Python异步编程: 揭秘异步编程的本质, 优化代码性能

本文将揭开异步编程的神秘面纱,探索异步编程的本质及其优势,并通过演示代码展示如何利用Python的异步编程特性优化代码性能,提高程序运行效率。
Python异步编程: 揭秘异步编程的本质, 优化代码性能
2024-02-25

Python异步编程: 揭开异步编程的神秘面纱, 提升代码效率

Python异步编程是一种高效的编程范式,它通过非阻塞I/O来提升代码的运行效率,本文将揭开异步编程的神秘面纱,带你领略异步编程的魅力,并通过演示代码展示其应用。
Python异步编程: 揭开异步编程的神秘面纱, 提升代码效率
2024-02-25

Java异步编程中如何进行FutureTask源码分析

本篇文章给大家分享的是有关Java异步编程中如何进行FutureTask源码分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java的异步编程是一项非常常用的多线程技术。但之
2023-06-19

JS中的async与await异步编程及await使用陷阱源码分析

这篇“JS中的async与await异步编程及await使用陷阱源码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JS中
2023-07-05

Python异步编程: 实现高效并发的异步代码之道

Python异步编程可以提高程序的性能和效率,允许程序同时处理多个任务,而不必等待每个任务都完成。在本文中,我们将探讨Python异步编程的概念,并通过示例演示如何编写异步代码。
Python异步编程: 实现高效并发的异步代码之道
2024-02-25

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录