Django3.0 异步通信初体验(小结)

此前博主曾经写过一篇博文,介绍了Django3.0的新特性,其中最主要的就是加入对ASGI的支持,实现全双工的异步通信。

2019年12月2日,Django终于正式发布了3.0版本。怀着无比的期待,我们来尝试一下吧!

(附ASGI官方文档地址:https://asgi.readthedocs.io/en/latest/extensions.html

一、创建Django3工程

利用Pycharm的方便,直接通过virtualenv创建虚拟环境,并安装Django3.0。

打开控制台,看看都安装了哪些库:

(venv) D:\work\for_test\django3>pip list
Package  Version

------

asgiref  3.2.3
Django   3.0
pip    10.0.1
pytz    2019.3
setuptools 39.1.0
sqlparse  0.3.0

除了pytz和sqlparse,又自动安装了asgiref。

asigref由Django软件基金会开发和维护,是一个Django生态中的库。

先启动一下服务器,看看Django是否正常运行:

没毛病,可以把服务器关了!

二、学习官方文档

毕竟是非常重要和复杂的新特性,先到官网取取经,看看文档怎么写的。

找了一圈,What?就这么点东西?

先康康吧。

How to deploy with ASGI
As well as WSGI, Django also supports deploying on ASGI, the emerging Python standard for asynchronous web servers and applications.

Django's startproject management command sets up a default ASGI configuration for you, which you can tweak as needed for your project, and direct any ASGI-compliant application server to use.

Django includes getting-started documentation for the following ASGI servers:

How to use Django with Daphne
How to use Django with Uvicorn
The application object
Like WSGI, ASGI has you supply an application callable which the application server uses to communicate with your code. It's commonly provided as an object named application in a Python module accessible to the server.

The startproject command creates a file <project_name>/asgi.py that contains such an application callable.

It's not used by the development server (runserver), but can be used by any ASGI server either in development or in production.

ASGI servers usually take the path to the application callable as a string; for most Django projects, this will look like myproject.asgi:application.

Warning

While Django's default ASGI handler will run all your code in a synchronous thread, if you choose to run your own async handler you must be aware of async-safety.

Do not call blocking synchronous functions or libraries in any async code. Django prevents you from doing this with the parts of Django that are not async-safe, but the same may not be true of third-party apps or Python libraries.

Configuring the settings module
When the ASGI server loads your application, Django needs to import the settings module — that's where your entire application is defined.

Django uses the DJANGO_SETTINGS_MODULE environment variable to locate the appropriate settings module. It must contain the dotted path to the settings module. You can use a different value for development and production; it all depends on how you organize your settings.

If this variable isn't set, the default asgi.py sets it to mysite.settings, where mysite is the name of your project.

Applying ASGI middleware
To apply ASGI middleware, or to embed Django in another ASGI application, you can wrap Django's application object in the asgi.py file. For example:

from some_asgi_library import AmazingMiddleware
application = AmazingMiddleware(application)

文档短小无力,内容稀少!

总结就以下几点:

  • 不能用python manage.py runserver的方式启动ASGI服务器,这只会启动传统的、默认的WSGI服务器,也就是老版本的东西
  • 要启动ASGI服务器,你需要使用Daphne或者Uvicorn。推荐使用Daphne,这是Django软件基金会开发的一个基于ASGI (HTTP/WebSocket)的服务器。
  • 有一个myproject.asgi:application文件,是ASGI通信的接口,Django默认自带
  • 你可以配置DJANGO_SETTINGS_MODULE 环境,或者使用默认的your_project.settings
  • 可以使用第三方ASGI中间件

再简单粗暴点,全文的意思是,你需要安装Daphne,然后调用Django的application来启动ASGI服务器。

好吧,我们看看Daphne,点击Django给的连接,跳转到相关页面,内容更少:

How to use Django with Daphne
Daphne is a pure-Python ASGI server for UNIX, maintained by members of the Django project. It acts as the reference server for ASGI.

Installing Daphne
You can install Daphne with pip:

python -m pip install daphne
Running Django in Daphne
When Daphne is installed, a daphne command is available which starts the Daphne server process. At its simplest, Daphne needs to be called with the location of a module containing an ASGI application object, followed by what the application is called (separated by a colon).

For a typical Django project, invoking Daphne would look like:

daphne myproject.asgi:application
This will start one process listening on 127.0.0.1:8000. It requires that your project be on the Python path; to ensure that run this command from the same directory as your manage.py file.

翻译过来就是:

  • pip安装daphne
  • 执行daphne myproject.asgi:application命令,启动ASGI服务器
  • 浏览器访问127.0.0.1:8000

咱们照做!

三、启动ASGI服务器

通过pip install daphne即可安装最新版本的daphne:

Collecting pycparser (from cffi!=1.11.3,>=1.8->cryptography>=2.7->autobahn>=0.18->daphne)
Installing collected packages: idna, hyperlink, zope.interface, attrs, six, Automat, constantly, PyHamcrest, incremental, pycparser, cffi, cry
ptography, pyopenssl, pyasn1, pyasn1-modules, service-identity, twisted, txaio, autobahn, daphne
Successfully installed Automat-0.8.0 PyHamcrest-1.9.0 attrs-19.3.0 autobahn-19.11.1 cffi-1.13.2 constantly-15.1.0 cryptography-2.8 daphne-2.4.
0 hyperlink-19.0.0 idna-2.8 incremental-17.5.0 pyasn1-0.4.8 pyasn1-modules-0.2.7 pycparser-2.19 pyopenssl-19.1.0 service-identity-18.1.0 six-1
.13.0 twisted-19.10.0 txaio-18.8.1 zope.interface-4.7.1

为了安装daphne,需要额外安装这么多依赖包!我们再pip list看一下:

(venv) D:\work\for_test\django3>pip list
Package     Version
---------------- -------
asgiref     3.2.3
attrs      19.3.0
autobahn     19.11.1
Automat     0.8.0
cffi       1.13.2
constantly    15.1.0
cryptography   2.8
daphne      2.4.0
Django      3.0
hyperlink    19.0.0
idna       2.8
incremental   17.5.0
pip       10.0.1
pyasn1      0.4.8
pyasn1-modules  0.2.7
pycparser    2.19
PyHamcrest    1.9.0
pyOpenSSL    19.1.0
pytz       2019.3
service-identity 18.1.0
setuptools    39.1.0
six       1.13.0
sqlparse     0.3.0
Twisted     19.10.0
txaio      18.8.1
zope.interface  4.7.1

不管了,就当没看见。

安装成功后,我们会获得一个daphne可执行命令,下面我们来启动服务器吧。

执行daphne django3.asgi:application命令。(将其中的django3换成你的工程名字,在manage.py文件所在的路径下执行)

(venv) D:\work\for_test\django3>daphne django3.asgi:application
2019-12-04 10:20:07,637 INFO   Starting server at tcp:port=8000:interface=127.0.0.1
2019-12-04 10:20:07,637 INFO   HTTP/2 support not enabled (install the http2 and tls Twisted extras)
2019-12-04 10:20:07,637 INFO   Configuring endpoint tcp:port=8000:interface=127.0.0.1
2019-12-04 10:20:07,637 INFO   Listening on TCP address 127.0.0.1:8000

当然,我们也是可以指定ip和port等参数的,详细请学习daphne文档https://pypi.org/project/daphne/

读一下人家的启动信息:

  1. 默认启动地址是127.0.0.1:8000
  2. 没有开启HTTP/2的支持(需要安装额外的包)
  3. 配置了端点,开始监听端口

Nice,通过浏览器来访问一下吧!

依然是熟悉的白底火箭图!图片我就不贴了,看起来没问题。

可是,这是基于HTTP的同步通信,还不是异步请求!让我们尝试一下websocket吧!

四、尝试Websocket

浏览器中按F12进入‘坦克模式',再进入console控制台,尝试发送一个Websocket请求:

忽视前面的css问题,重点在于这个ws请求,居然无法建立连接!返回状态码500,也就是服务器错误!

再看看Pycharm后台的信息:

127.0.0.1:5991 - - [04/Dec/2019:10:30:05] "WSCONNECTING /" - -
2019-12-04 10:30:05,246 ERROR  Exception inside application: Django can only handle ASGI/HTTP connections, not websocket.
 File "d:\work\for_test\django3\venv\lib\site-packages\daphne\cli.py", line 30, in asgi
  await self.app(scope, receive, send)
 File "d:\work\for_test\django3\venv\lib\site-packages\django\core\handlers\asgi.py", line 146, in __call__
  % scope['type']
 Django can only handle ASGI/HTTP connections, not websocket.
127.0.0.1:5991 - - [04/Dec/2019:10:30:05] "WSDISCONNECT /" - -

重点在这句Django can only handle ASGI/HTTP connections, not websocket.

什么?Django不支持Websocket?说好的ASGI,说好的全双工异步通信呢?

难道是我哪里搞错了?不行,我得看看源码去!

五、Django3.0源码

一路点点点,翻了个遍,发现Django3.0与之前的2.2关于ASGI的区别就是多了下面两个文件:

django.core.asgi很简单,一看就懂,不多说:

import django
from django.core.handlers.asgi import ASGIHandler

def get_asgi_application():
  django.setup(set_prefix=False)
  return ASGIHandler()

关键是django.core.handlers.asgi这个文件,不到300行,总共就2个类,代码就不贴了:

  • ASGIRequest:继承了HttpRequest类,一看就知道是构造请求对象
  • ASGIHandler:继承了base.BaseHandler,这个就类似WSGIHandler,用于具体处理ASGI请求

让我们看看它的其中一段代码:

# Serve only HTTP connections.
# FIXME: Allow to override this.
if scope['type'] != 'http':
  raise ValueError(
    'Django can only handle ASGI/HTTP connections, not %s.'
    % scope['type']
  )

这就是我们前面在浏览器中发送ws请求,但是无法建立连接的原因!

如果scope的type属性不是http,那么弹出ValueError异常,并提示不支持该类连接!

再看看人家写的注释,明明白白的写着Serve only HTTP connections. FIXME: Allow to override this.。翻译过来就是只支持HTTP连接,请自己重写这部分内容修复这个缺陷。FIXME!FIXME!

好吧,我承认白高兴了一场。

六、总结

与Django3.0关于异步通信的初体验很不好,有下面几点猜测:

  • 可能我水平不行,不会用Django
  • 可能不是通过Websocket,而是别的手段与ASGI通信
  • Django真的目前只提供了个接口,内部实现还没做

由于相关资料太少,多方查找,据说:

  • Django会在后续的版本陆续实现完整的原生的异步通信能力,从同步机制切换到可兼容的异步机制
  • 目前3.0阶段,要与websocket通信依然得通过django-channel库,还不是原生支持

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Django+uni-app实现数据通信中的请求跨域的示例代码

    前后端分离的模式下,后端使用Django RestFramework,前端使用uni-app来进行APP的开发. 前端代码: Django后端跨域配置 settings.py配置文件中添加: INSTALLED_APPS = [ 'corsheaders', ] 中间件中添加 'corsheaders.middleware.CorsMiddleware', # 注意顺序 一定是在common中间件的前面 MIDDLEWARE = [ # 'accounts.MyCsrfMiddleware.CO

  • Django3.0 异步通信初体验(小结)

    此前博主曾经写过一篇博文,介绍了Django3.0的新特性,其中最主要的就是加入对ASGI的支持,实现全双工的异步通信. 2019年12月2日,Django终于正式发布了3.0版本.怀着无比的期待,我们来尝试一下吧! (附ASGI官方文档地址:https://asgi.readthedocs.io/en/latest/extensions.html) 一.创建Django3工程 利用Pycharm的方便,直接通过virtualenv创建虚拟环境,并安装Django3.0. 打开控制台,看看都安装

  • v语言初体验小结

    最近github上开源了一个"新语言"vlang,火的不得了,我不信,于是乎,尝试了一下,真香. 以下内存均来自https://www.v-lang.cnv语言文档 by 20190701 ubuntu安装vlang 依赖安装 这里采用的是ubuntu的机器,centos的会报错,暂时没有去操作 查看机器型号 $ uname -a Linux liwang 4.15.0-54-generic #58-Ubuntu SMP Mon Jun 24 10:55:24 UTC 2019 x86

  • vue-cli3+typescript初体验小结

    前言 气势汹涌,ts似乎已经在来的路上,随时可能敲门. 2015年,三大前端框架开始火爆的时候,我还在抱着Backbone不放,一直觉得可以轻易转到其他框架去.后来换工作,现实把脸都打肿了,没做过vue.react.angular?不要! 今天,不能犯这个错了,毕竟时不我与,都快奔三了. vue-cli3 vue-cli3的详细功能推荐官方文档,不在本文介绍范围内. 安装: npm install -g @vue/cli 检查安装成功与否: vue --version 创建项目: vue cre

  • 浅谈vue-cli 3.0.x 初体验

    最近项目正在优化.乘着有时间看了一下 vue-cli3.0.x 使用 .感觉还蛮不错的. 因为之前项目使用的 vue-cli 2 创建的,强行使用 eslint让我们很难受,一些与项目无关的 "build" 和 "config" ,让人看着就有一些不爽 .由于公司环境比较多,需要测试环境的配置.增加了 ""tt": "node build/tt-build.js"" .到 3.0.x 应该怎么用? 带着这些

  • DevEco Studio 2.0开发鸿蒙HarmonyOS应用初体验全面测评(推荐)

    在9月10日召开的华为开发者大会上,宣布了鸿蒙2.0系统正式面世,同时开启了Beta版本的测试和开源网站.对于开发者来说两个最关键的点值得关注:一个是Beta版的开发工具,一个是开源网站. 一.开源网站 在开发者大会上宣布将HarmonyOS源代码捐赠给中国开放原子开源基金会,并在大会上公布了鸿蒙系统的开源路线. 官网地址: OpenHarmony 官方源码地址 二.开发工具 鸿蒙使用基于Intellij IDEA深度定制研发的DevEco Studio作为其开发工具.官方下载地址如下: Dev

  • 详解Vue3.0 + TypeScript + Vite初体验

    项目创建 npm: $ npm init vite-app <project-name> $ cd <project-name> $ npm install $ npm run dev or yarn: $ yarn create vite-app <project-name> $ cd <project-name> $ yarn $ yarn dev 项目结构 main.js 在个人想法上,我觉得createApp()是vue应用的实例,createApp

  • vue.js 初体验之Chrome 插件开发实录

    背景 对于经常和动画开发打交道的开发者对于Animate.css这个动画库不会陌生,它把一些常见的动画效果都封装起来了,非常实用.但是有时候在开发中,仅仅只是需要某一两个动画效果,把整个CSS文件都引入,这样不是太好. 需求就出现了,能不能有一个工具可以直接预览Animate.css对应的动画效果,并且生成对应的动画代码呢? 作为一个UI开发,平时跟Chrome浏览器打交道最多,于是就整了一个Chrome插件可以及时预览对应Animate.css中的动画效果并生成对应的动画代码,这样在实际开发中

  • NetCore1.1+Linux部署初体验

    NetCore1.1+Linux部署初体验 1.环境准备 Centaos7+Win10 虚拟机 Win10安装VS2017 注意勾选下.Net Core 3.Centaos安装netcore 1.1参见https://www.microsoft.com/net/core sudo yum install libunwind libicu curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?linkid=848821 sudo m

  • Visual Studio for Mac版 初体验

    你喜爱的 IDE,现在可用于 Mac.因为在 Visual Studio for Mac 之前,已经有了 Visual Studio Code for Mac,那时候我们还以为 Visual Studio Code 就是 Visual Studio 的跨平台版本,但事实微软并不是这样想的,Visual Studio Code 相对于 Visual Studio 还是太简化了,企业级的应用开发 Visual Studio Code 还是有些力不从心,所以 Visual Studio for Mac

  • AJAX初体验之实战篇——打造博客无刷新搜索

    如果你对AJAX不是很了解,可以先看看这篇教程的前篇<AJAX初体验之上手篇>. 现在博客很流行,相信应该上网时间稍微长点的朋友都会在这或者在那的有一个自己的博客.对于一些有一定能力的朋友,可能更喜欢自己去下载一个博客程序来架设一个自己的博客,而不是使用一些博客网站提供的服务.而大部分博客程序所带的搜索功能是提交查询关键字到搜索页面,然后在后台生成搜索结果,再呈现给用户,这过程之中浪费了一些带宽,如博客的侧边栏.要节约这一些带宽,我们可以用AJAX来打造自己的无刷新日志搜索. 在本篇教程中,数

随机推荐