上周Django
官方正式发布了Django 3.0
版本,其中最重要的更新莫过于对ASGI
的支持。今天对Django 3.0
的异步功能作了简单的试用,分析下过程,但愿对你们有帮助。html
具体的详细更新列表可参考官方 Django 3.0 release notes, 这里再也不赘述,下面咱们开始。python
在开始以前咱们先来准备下环境,直接使用 Pycharm 新建一个项目,并新建虚拟环境.git
获得以下项目:github
相比以前版本的 django 项目,多了一个asgi.py
。这即是ASGI
的服务的入口文件了,内容基本同wsgi.py
。web
在使用ASGI
特性以前,先让咱们了解下,什么是 ASGI?django
ASGI
和WSGI
,都是一种 Web 服务网关接口协议,是在CGI
的标准上构建的。浏览器
CGI
(通用网关接口, Common Gateway Interface),简单来讲就是解析浏览器等客户端发送给服务端的请求,并组装须要返回的 HTTP 请求的一种通用协议,处理这个过程的程序,咱们就能够叫 CGI 脚本。互联网早起的动态网页都是基于CGI
标准的。缓存
WSGI
,是一种 Python 专用的 Web 服务器网关接口,它分为两部分"服务器(或网关)"和"应用程序(或应用框架)"。「服务器」,通常独立于应用框架,为应用程序运行提供环境信息和一个回调函数(Callback Function)。当应用程序完成处理请求后,透过回调函数,将结果回传给服务器。经常使用的WSGI
服务器有: uwsgi
、gunicon
。「应用程序」,是各类实现了WSGI
标准的 Python web 框架了,经常使用的有Django
、Flask
等。bash
ASGI
(Asynchronous Server Gateway Interface)是 Django 团队提出的一种具备异步功能的 Python web 服务器网关接口协议。可以处理多种通用的协议类型,包括 HTTP,HTTP2 和 WebSocket。WSGI
是基于 HTTP 协议模式的,不支持WebSocket
,而ASGI
的诞生则是为了解决 Python 经常使用的 WSGI 不支持当前 Web 开发中的一些新的协议标准(WebSocket、Http2 等)。同时,ASGI
向下兼容WSGI
标准,能够经过一些方法跑WSGI
的应用程序。经常使用的「服务器」有Daphne
、Uvicorn
。服务器
更多ASGI
资料可参考文档
了解了ASGI
,咱们进入正题。关于ASGI
在Django release Notes
文档中并无过多的介绍,只有一个部署的文档 How to deploy with ASGI
看了下,主要说了两种部署方式:daphne 和 uvicorn。其中"必须使用 Daphne
或Uvicorn
部署,才会是 ASGI 服务,直接 runnerserver 是同步服务"这句给了咱们提醒,想要使用 ASGI,便不能直接 runerserver。
咱们随便选一种使用方式,并启动服务:
# 安装
pip install uvicorn
# 启动服务
uvicorn django3_demo.asgi:application
复制代码
启动日志以下:
$ uvicorn django3_demo.asgi:application
INFO: Started server process [48508]
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Waiting for application startup.
INFO: ASGI 'lifespan' protocol appears unsupported.
INFO: Application startup complete.
复制代码
根据ASGI
的特性,能够支持 HTTP、HTTP2 和 WebSocket。那咱们来进行下 websocket 和 http 的测试。
打开浏览器 console 控制台,新建一个 websocket 连接,出现以下错误:
看服务错误以下:
INFO: Application startup complete.
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/Users/xiumin1/.local/share/virtualenvs/django3_demo/lib/python3.6/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 153, in run_asgi
result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
File "/Users/xiumin1/.local/share/virtualenvs/django3_demo/lib/python3.6/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/Users/xiumin1/.local/share/virtualenvs/django3_demo/lib/python3.6/site-packages/django/core/handlers/asgi.py", line 146, in __call__
% scope['type']
ValueError: Django can only handle ASGI/HTTP connections, not websocket.
复制代码
Django can only handle ASGI/HTTP connections, not websocket
,貌似 Django 的 ASGI 尚未彻底实现,仅支持 HTTP。
在浏览器输入http://127.0.0.1:8000
出现了咱们熟悉的小火箭页面。这只是简单的启动页面,咱们须要写个异步的 view 和 model 来具体操做下。
翻阅了一遍文档,在一个小角落里:
令我失望的找到了以下说明:
Django has developing support for asynchronous (“async”) Python, but does not yet support asynchronous views or middleware; they will be coming in a future release.
主要意思是现阶段不支持异步的 view 和中间件。那也就说明无法使用 Django 原生的方式来实现ASGI
了。
到此,异步功能的试用告一段落。结论,现阶段Django
原生仍是没法彻底的支持ASGI
的服务。若是想彻底实现ASGI
服务,仍是须要 Channels
或 starlette
。
通过翻阅资料,我找到了 Django 原生异步主要推进者Andrew Godwin的一篇博客, 描述了异步功能开发的时间轴。大体以下:
从如今 3.0 发布的功能看,实现貌似与该时间抽差了一个版本,只实现了应该到 2.2 的功能。
到这里今天的分享就结束了。最后,仍是但愿 Django 的异步功能早点来临,到时候咱们便能直接使用 django 开发各类异步特性的功能,而没必要安装三方软件。