如何用Django频道构建聊天应用程序

390 阅读3分钟

用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

500 Internal Server Error

创建聊天应用程序

在独立的应用程序中分离聊天的代码是一个好的做法。按照Django的方式来创建一个应用程序。

$ python manage.py startapp letschat_app'

将新的应用程序添加到settings.py 文件内的已安装应用程序部分。

接下来,创建一个letschat/template/letschat_app 目录,然后制作一个名为index 的HTML文件。

导航到index.html ,添加下面的锅炉代码。

Index Page

该HTML模板代码允许客户输入他们正在浏览的聊天室的名称。

提交的房间名称将被附加到windows路径上,并被发送到服务器上。服务器将接收该请求,如果找到的话,将其与URL相匹配。

我们必须同时制作URLsviews ,用于客户端传入的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 ,并输入下面的代码片段。

ChatRoom Page 1

ChatRoom Page 2

注意:这两个代码片断是彼此的延续。

区分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/ ;你应该确认下面的图像。

Room 1

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

Room 2

但我们必须制作一个接受WebSocket连接的消费者。

让消费者接受连接

历史上,Django服务器将URLConf路由到适当的视图函数并发送Html模板。当使用Daphne服务器的Channels收到任何请求时也是如此,它将路由映射到消费者,并查找到适当的功能。

在聊天应用程序文件夹中制作consumers.py 文件,并使用下面图片中的代码片段。

Consumer 1

Consumer 2

使用的正则表达式解决了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
        )
    ),
})

最后一步是启用一个通道层,以允许来自不同客户端的多个聊天连接。这个层背后的抽象是。

  1. 每个频道都有一个名字,任何有这个名字的客户端都可以发送消息,因为很多服务器仍然在运行。
  2. 频道层也可以被分组。每个组都有一个名字,任何人都可以删除或添加一个有确切名字的通道。

我们将使用通道层,使用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

现在你有一个功能性的基本聊天应用程序。这将使你在项目前做好准备,并指导你避免枯燥的文档。