Django3.0 asynchronous communication early experience

Previously blogger wrote a blog post describes the new features Django3.0, the most important is the addition of support for ASGI achieve full-duplex asynchronous communication.

December 2, 2019, Django finally released the 3.0 version. With an unparalleled look, let's try it!

(Official documents attached ASGI address: https://asgi.readthedocs.io/en/latest/extensions.html )

First, create a project Django3

1575424609514

Use convenient Pycharm to create a virtual environment directly through virtualenv, and install Django3.0.

Open the console to see which libraries are installed:

(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

In addition to pytz and sqlparse, and automatically installed asgiref.

asigref by the Django Software Foundation development and maintenance, it is a Django Ecology library.

First start at the server and see if Django running:

1575424868819

Nothing wrong with the server can be shut!

Second, the study official documents

After all, it is very important and complex new features, first learn to take the official website to see how to write the document.

Find a circle, What? It's that something?

1575425030020

Kankan before it.

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)

Inability short document, the contents of rare!

Summary on the following points:

  • ASGI server can not start with a python manage.py runserver way, it will only start traditional default WSGI server, which is the old version of things
  • To start ASGI server, you need to use Daphne or Uvicorn. Recommended Daphne, which is based on ASGI (HTTP / WebSocket) server Django Software Foundation development.
  • There is a myproject.asgi:applicationdocument, a communication interface to ASGI, Django comes with default
  • You can configure the DJANGO_SETTINGS_MODULEenvironment, or use the defaultyour_project.settings
  • You can use a third-party middleware ASGI

Then simple and crude point, the full text mean is that you need to install the Daphne, and then call the application Django to start ASGI server.

Well, we look at Daphne, click on Django's connection to jump to the relevant page content less:

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.

Translation:

  1. pip安装daphne
  2. 执行daphne myproject.asgi:application命令,启动ASGI服务器
  3. 浏览器访问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/

读一下人家的启动信息:

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

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

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

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

四、尝试Websocket

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

1575426639860

忽视前面的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的区别就是多了下面两个文件:

1575427104722

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

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

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

The key is django.core.handlers.asgithis file, less than 300 lines, a total of just two classes, the code is not posted:

  • ASGIRequest: inherited HttpRequest class, to see that this request is to construct objects
  • ASGIHandler: inherited base.BaseHandler, this on a similar WSGIHandler, requests for specific processing ASGI

Let's see where it's a piece of code:

# 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']
    )

This is our earlier request sent ws in the browser, but why the connection could not be established!

If the scope of the type attribute is not http, then pop ValueError exception, and prompts are not supported type of connection!

Look at other people write notes, plain written Serve only HTTP connections. FIXME: Allow to override this.. Translates only supports HTTP connection, own rewrite this section to repair this defect. FIXME! FIXME!

Okay, I admit Bai Gaoxing a second time.

VI Summary

About Django3.0 first experience with asynchronous communication is very bad, there is speculation that the following points:

  1. Probably not my level, not by Django
  2. Probably not by Websocket, but other means of communication with the ASGI
  3. Django really is currently only available interfaces, internal implementations do not

Because little information, extensive searches, it is said:

  1. Django will continue in subsequent versions of the full realization native asynchronous communication capabilities, synchronization mechanisms to switch from a compatible asynchronous mechanism
  2. 3.0 At present stage, we should still have to communicate with websocket by django-channel library, is not native support

Well, the thing about Django3.0 stop here, more Django tutorials and blog, you can visit my official website http://www.liujiangblog.com, or my collection of micro-channel public number ' Django之家'. If there are errors in the text content, like him criticism and thank you!

Guess you like

Origin www.cnblogs.com/django-dev/p/11981970.html