用Django通道构建聊天应用程序
本教程将通过使用Django Channel实现聊天服务器来构建一个功能齐全的聊天应用程序。这个通道是在Django使用的异步服务器上实现的。这个服务器被命名为Asynchronous Server Gateway InterfaceASGI 。
ASGI是Channel所依据的服务器规范。和WSGI一样,服务器和框架都可以选择,而不是只接受Channel的服务器。
Django Channel支持HTTP和其他类型的协议,连接时间长。Channel层将整个应用程序划分为进程,并支持Django视图的一部分。
前提条件
- 对Django和Python的了解。
- 安装了喜爱的代码编辑器。我使用[Visual Studio Code]。
- 在你的机器上安装[Docker]。
- 在你的机器上安装[Redis]。
项目设置
让我们开始构建聊天应用程序。导航到你的终端,并遵循以下过程。
$ django-admin startproject letschat
$ cd letschat
让我们安装channel的依赖关系并制作需求文件。
$ pip install channels
$ pip freeze > req.txt
在settings.py 文件中添加通道库到应用程序中。用下面的代码编辑letschat 文件夹中的asgi.py 。
import os
from channels.routing import ProtocolTypeRouter
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'letschat.settings')
application = ProtocolTypeRouter({
"http": get_asgi_application()
})
最后,ASGI 服务器必须指向asgi.py 文件。这将在settings.py 文件中完成。
注意:这将取代Django项目中默认的WSGI服务器。
ASGI_APPLICATION = "letschat.asgi.application"
Channel服务器将接管默认的Django的WSGI服务器,只允许使用上述代码的HTTP 协议。
用下面的命令运行服务器,然后用localhost打开浏览器,你应该看到500 internal server error 的信息。
$ python manage.py run server

创建聊天应用程序
在独立的应用程序中分离聊天的代码是一个好的做法。按照Django的方式来创建一个应用程序。
$ python manage.py startapp letschat_app'
将新的应用程序添加到settings.py 文件内的已安装应用程序部分。
接下来,创建一个letschat/template/letschat_app 目录,然后制作一个名为index 的HTML文件。
导航到index.html ,添加下面的锅炉代码。

该HTML模板代码允许客户输入他们正在浏览的聊天室的名称。
提交的房间名称将被附加到windows路径上,并被发送到服务器上。服务器将接收该请求,如果找到的话,将其与URL相匹配。
我们必须同时制作URLs 和views ,用于客户端传入的HTTP请求。
在聊天应用程序内部的views.py 文件中,我们可以将索引方法定义为。
# letschat_app/views.py
from django.shortcuts import render
def app_index(request):
return render(request, 'letschat_app/index.html')
为了调用视图,我们必须将其与URLConf 。在letschat_app 文件夹中制作urls.py 文件。
# letschat_app/urls.py
from django.urls import path
from .views import app_index
app_name = 'letschat_app'
urlpatterns = [
path('', app_index, name="index")
]
下一步是在项目中注册应用程序URLConf 文件。导航到letschat 文件夹中的urls.py ,并按以下方式映射。
from Django.URLs import path, include
urlpatterns = [
path('chat/', include('letschat_app.urls'))
]
现在用下面的命令运行你的服务器。
$ python manage.py runserver
当服务器运行时,导航到http://localhost:8080/chat/ ,打开聊天页面。输入和提交表格都会显示出来。
但如果你输入任何房间名称,你应该收到page not found ,因为我们没有实现任何其他聊天室的交流。
设置一个聊天服务器
首先,我们需要添加另一个房间聊天模板。在letschat/templates/letschat_app 目录内,创建chatroom.html ,并输入下面的代码片段。


注意:这两个代码片断是彼此的延续。
区分HTTP 连接和WebSockets的通用惯例是使用ws 协议。
在views.py 文件中,我们要做一个函数,通过URLs来匹配客户端的请求。
def room_name(request, name):
return render(request, 'letschat_app/chatroom.html', {'room_name': name})
这将抓取从请求中收到的任何房间名称,并将其发送到被渲染的HTML模板中。一旦收到,chatroom.html ,就会被打开进行聊天。
而URLs将是这样的。
from django.urls import path
from .views import room_name
urlpatterns = [
path('<str:name>/', room_name, name='room'),
]
当运行服务器时,做移动到http://localhost:8080/chats/ ;你应该确认下面的图像。

输入你选择的任何房间名称进行连接。这将打开像这样的聊天室。

但我们必须制作一个接受WebSocket连接的消费者。
让消费者接受连接
历史上,Django服务器将URLConf路由到适当的视图函数并发送Html模板。当使用Daphne服务器的Channels收到任何请求时也是如此,它将路由映射到消费者,并查找到适当的功能。
在聊天应用程序文件夹中制作consumers.py 文件,并使用下面图片中的代码片段。


使用的正则表达式解决了URLRouter 的限制。
另外,Consumer 类上的as_asgi() 方法与Django中基于类的视图方法做了同样的工作,即as_view() 。
现在我们要重定向到定义的socket URL。导航到asgi.py ,并按照下面的片段配置路由。
from channels.auth import AuthMiddlewareStack
import letschat_app.routing
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
letschat_app.routing.websocket_urlpatterns
)
),
})
最后一步是启用一个通道层,以允许来自不同客户端的多个聊天连接。这个层背后的抽象是。
- 每个频道都有一个名字,任何有这个名字的客户端都可以发送消息,因为很多服务器仍然在运行。
- 频道层也可以被分组。每个组都有一个名字,任何人都可以删除或添加一个有确切名字的通道。
我们将使用通道层,使用Redis 作为其内存存储。
这将有助于存储频繁的聊天,只要聊天服务器仍然处于连接状态。
现在,我们必须通过运行以下命令在默认端口6379 上启动Redis服务器。
$ docker run -p 6379:6379 -d redis:5
$ pip install channels_redis
这个docker命令将启动Redis镜像并在指定的端口上运行。然后我们安装了channel_redis ,这是连接内存存储所需的库。
在安装了依赖关系后,我们必须通过将下面的代码添加到settings.py ,就在ASGI_APPLICATION ,以跟踪各层。
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
通道层将指向Redis层作为其存储。这种连接是使用上面安装的库进行的。
该库需要一个BACKEND 配置和它的CONFIG 属性,该属性定义了主机,即本地运行的Redis服务器。
为了测试该应用程序,同时打开一个浏览器窗口和一个隐身标签窗口。并启动服务器。
$ python manage.py runserver
在网络浏览器上,在两个窗口中导航到http://127.0.0.1:8000/chats/room/,并输入信息。
您将在两个聊天记录中收到它们textarea 。
现在你有一个功能性的基本聊天应用程序。这将使你在项目前做好准备,并指导你避免枯燥的文档。