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
- 现在安装Django和Channels :
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://
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,你应该会看到如下输出:
查看服务器的日志。请注意,我们只创建了一次连接,并且可以多次发送消息而无需创建新连接。