📜  Django 频道 – 介绍和基本设置

📅  最后修改于: 2022-05-13 01:54:32.397000             🧑  作者: Mango

Django 频道 – 介绍和基本设置

Django 是用于 Web 开发的强大Python框架。它快速、安全且可靠。通道允许 Django 项目处理 HTTP 以及异步协议,如 WebSockets、MQTT、聊天机器人等。

频道:

通道保留了 Django 的同步行为,并添加了一层异步协议,允许用户编写完全同步、异步或两者混合的视图。通道基本上允许应用程序支持“长时间运行的连接”。它用它的ASGI替换了 Django 的默认WSGI

ASGI:

ASGI (异步服务器网关接口)提供异步Python Web 服务器和应用程序之间的接口,同时它支持 WSGI 提供的所有功能。

消费者:

消费者是渠道的基本单位。它是一个支持异步和同步应用程序的事件驱动类。消费者可以运行更长时间,因此他们支持需要持久连接的网络套接字。

在这篇文章中,我们将设置一个基本的通道示例。我们将构建一个计算器应用程序,它允许用户向服务器发送多个表达式并通过单个持久连接接收结果。



环境设置:

  • 为Python应用程序创建一个虚拟环境以避免版本冲突总是一个好主意。在终端中运行以下命令以开始使用
easy-install pip
python3 -m pip install virtualenv
virtualenv venv
source venv/bin/activate
  • 现在安装DjangoChannels
pip install django
pip install channels
# On windows, try an unofficial wheel of 'Twisted' in case of dependency errors

实时计算器应用程序:

现在启动一个 Django 项目并创建一个名为“liveCalculator”的应用程序

django-admin startproject sampleProject
cd sampleProject
python3 manage.py startapp liveCalculator

sampleProject/settings.py 中,注册频道liveCalculator

设置.py:

INSTALLED_APPS = [
   'channels',
   'liveCalculator',
   'django.contrib.admin',
   'django.contrib.auth',
   'django.contrib.contenttypes',
   'django.contrib.sessions',
   'django.contrib.messages',
   'django.contrib.staticfiles',
]

在 sampleProject/asgi.py 中,添加 http 协议。

asgi.py:

Python3
import os
  
import django
from channels.http import AsgiHandler
from channels.routing import ProtocolTypeRouter
  
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sampleProject.settings')
django.setup()
  
application = ProtocolTypeRouter({
  "http": AsgiHandler(),
  # Just HTTP for now. (We can add other protocols later.)
})


HTML


  

    
    
    Live Calculator

  

    
    Enter the expression:             


Python3
from django.shortcuts import render
  
# Create your views here.
  
def index(request):
    return render(request, 'liveCalculator/index.html', {})


Python3
from django.conf.urls import url
from . import views
  
urlpatterns = [
    url(r'^$', views.index, name="index"),
]


Python3
from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^', include('liveCalculator.urls'))
]


Python3
import json
from channels.generic.websocket import WebsocketConsumer
  
class Calculator(WebsocketConsumer):
    def connect(self):
        self.accept()
  
    def disconnect(self, close_code):
        self.close()   
  
    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        expression = text_data_json['expression']
        try:
            result = eval(expression)
        except Exception as e:
            result = "Invalid Expression"
        self.send(text_data=json.dumps({
            'result': result
        }))


Python3
from django.urls import re_path
  
from . import consumers
  
websocket_urlpatterns = [
    re_path(r'ws/livec/$', consumers.Calculator.as_asgi()),
]


Python3
import os
  
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import liveCalculator.routing
  
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sampleProject.settings")
  
application = ProtocolTypeRouter({
  "http": get_asgi_application(),
  "websocket": AuthMiddlewareStack(
        URLRouter(
            liveCalculator.routing.websocket_urlpatterns
        )
    ),
})


现在我们需要将这个 asgi 注册到我们的应用程序中。在 sampleProject/settings.py 中添加这一行:

ASGI_APPLICATION = "sampleProject.asgi.application"

创建一个新文件夹liveCalculator/templates/liveCalculator并在其中创建一个新文件index.html 。这将是我们应用程序的起始页面。在index.html 中添加以下代码



索引.html:

HTML



  

    
    
    Live Calculator

  

    
    Enter the expression:             

上面的代码将呈现一个文本区域和一个输入框,用户可以在其中输入表达式。它将创建一个我们稍后将进行的套接字连接,并将接收到的结果附加到文本区域中。当用户输入表达式时,它将通过套接字连接发送表达式。

现在在liveCalculator/views.py 中创建一个视图来呈现这个页面:

liveCalculator/views.py:

蟒蛇3

from django.shortcuts import render
  
# Create your views here.
  
def index(request):
    return render(request, 'liveCalculator/index.html', {})

接下来,我们需要为这个视图创建一个路由。在liveCalculator目录中添加一个新文件urls.py并添加以下代码:

liveCalculator/urls.py:

蟒蛇3

from django.conf.urls import url
from . import views
  
urlpatterns = [
    url(r'^$', views.index, name="index"),
]

sampleProject/urls.py 中注册此路由:

示例项目/urls.py:



蟒蛇3

from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^', include('liveCalculator.urls'))
]

现在我们需要为我们的网络套接字连接创建消费者。我们将使用通用的WebsocketConsumer类来实现其事件驱动的方法。在liveCalculator文件夹中新建一个文件consumer.py并添加以下代码:

消费者.py:

蟒蛇3

import json
from channels.generic.websocket import WebsocketConsumer
  
class Calculator(WebsocketConsumer):
    def connect(self):
        self.accept()
  
    def disconnect(self, close_code):
        self.close()   
  
    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        expression = text_data_json['expression']
        try:
            result = eval(expression)
        except Exception as e:
            result = "Invalid Expression"
        self.send(text_data=json.dumps({
            'result': result
        }))

WebsocketConsumer类支持这些用户定义的方法:

  • connect() :我们可以编写客户端发送连接请求时应该发生什么的业务逻辑。
  • disconnect() :我们可以编写客户端发送断开连接请求时应该发生什么的业务逻辑。
  • receive():我们可以编写客户端发送消息时应该发生什么的业务逻辑。

它还支持这些内置方法:

  • accept():它将接受传入的连接。
  • close():关闭当前连接。
  • send():将指定的消息发送给客户端。

我们在Calculator类中简单地使用了上述方法来接受连接,在收到消息时评估表达式,并将其发送给客户端。

接下来,我们还需要为这个消费者定义路由方法。在同一文件夹中新建一个文件routing.py ,并在其中添加以下代码:

路由.py:

蟒蛇3

from django.urls import re_path
  
from . import consumers
  
websocket_urlpatterns = [
    re_path(r'ws/livec/$', consumers.Calculator.as_asgi()),
]

请注意,我们在 Calculator 类中使用了as_asgi()方法来将其用于我们的应用程序。这将启用ws:///ws/livec 上的套接字。现在通过声明WebSocket协议将routing.py注册到asgi.py 中



asgi.py:

蟒蛇3

import os
  
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import liveCalculator.routing
  
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sampleProject.settings")
  
application = ProtocolTypeRouter({
  "http": get_asgi_application(),
  "websocket": AuthMiddlewareStack(
        URLRouter(
            liveCalculator.routing.websocket_urlpatterns
        )
    ),
})

我们几乎完成了我们的第一个 Channels 应用程序。保存所有文件并在终端中运行以下命令:

python3 manage.py makemigrations
python3 manage.py migrate
python3 manage.py runserver

现在在浏览器上打开 http://localhost:8000,你应该会看到如下输出:

查看服务器的日志。请注意,我们只创建了一次连接,并且可以多次发送消息而无需创建新连接。