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

图片

异步服务网关接口(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个参数,分别为 scopereceive和send示例代码如下

async def app(scopereceive, 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(scopereceive, 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 Truemessage = 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 Truemessage = 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
    elseraise NotImplementedError()

02、Uvicorn

Uvicorn是ASGI的一个协议层实现,一个轻量级的ASGI服务器,基于uvloophttptools实现运行速度极快。

uvloop是一个高效的基于异步IO 的事件循环框架底层实现libuv承载。libuv是一个使用C语言开发的支持高并发的异步IO 库,由Node.js作者开发,作为Node.js底层IO 库实现,如今已经发展得相当成熟稳定。

使用Uvicorn需要通过命令pip install uvicorn安装依赖项,项目结构如图2所示

接下来终端输入uvicorn asgiapp以启动服务器效果如图3所示

图片

■ 图2  ASGI项目文件结构

 

图片

 ■ 图3  启动ASGI服务器

服务器启动后,可使用浏览器通过http://127.0.0.1:8000访问站点结果如图4所示

为了向用户提供更加安全服务,现代网站需要支持HTTPS,Uvicorn 也提供了对HTTPS的支持,使用起来也相当方便。

首先准备好HTTPS证书文件,如图5所示

图片

■图4  页面访问结果

图片

 ■ 图5 证书文件所在目录

接下来通过命令uvicorn–sslcertfile ./ssl/cert.pemsslkeyfile ./ssl/cert.key asgiapp来启动服务器,如图6所示

图片

■ 图6  以HTTPS方式启动服务

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

FROM python:3-slim

RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple uvicorn

容器对应dockercompose.yml内容如下:

services:
  web:
    build:.
    restart:always
    tty:true
    ports:
      - "8000:8000"
    volumes:
      - ".:/opt/"
    working_dir:"/opt/"
    command:uvicorn --host 0.0.0.0 asgiapp

 03、源码

 

原文地址:https://blog.csdn.net/qq_41640218/article/details/132014936

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_21172.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注