使用 React 和 Django Channels 构建聊天应用程序

使用 Django 开发用于 HTTP 连接和应用程序请求的服务器很常见。 但是,在开发需要始终打开连接以进行双向连接的应用程序(如会议和聊天程序)时,使用 HTTP 连接效率低下。 在这种情况下,使用 WebSockets 是必不可少的。

通过使用 WebSockets,连接到该开放网络的所有用户都可以实时接收相关数据,这提供了一种在客户端和服务器之间建立双向连接的方法。 这是一个有状态的协议,这意味着在初始连接身份验证之后,客户端凭据被保存,并且在连接被破坏之前不需要进一步的身份验证。

在本教程中,我们将学习如何使用 Django 和 React 构建聊天应用程序。 在本教程之后,您应该更熟悉 WebSockets 在 Django 和 React 中的工作方式。 要继续阅读本文,您需要:

  • 对Django的基本了解
  • 已安装 Django v3.2
  • 对 React 的基本了解

您可以在 GitHub 上 找到完整的应用程序。 让我们开始吧!

  • WebSocket 功能
  • 如何在 Django 中使用 WebSocket
  • 构建前端
  • 测试应用程序

WebSocket 功能

WebSocket 是一种双向协议,这意味着数据可以在客户端和服务器之间即时交换而不会中断。 同理,WebSockets 也被视为全双工通信。

WebSockets 不需要任何特定的浏览器即可工作; 所有浏览器都兼容。 WebSocket 是一个有状态的协议。 由于客户端凭据是在主连接验证后保存的,因此在连接丢失之前不需要再次进行额外的身份验证。

如何在 Django 中使用 WebSocket

当你想用 WebSockets 做任何事情时, Django Channels 是必不可少的,所以继续使用以下命令安装它:

pip install channels

在本节中,我们将设置 Django 以使用 WebSockets,并将其与构建普通的 Django 应用程序进行比较。

感谢 Django Channels,在 Django 中使用 WebSockets 很简单。 您可以使用 Django Channels 构建一个 ASGI (异步服务器网关接口)服务器,之后您可以构建一个组,成员可以在其中即时互相发短信。 交流不是与特定用户,而是与一个组,任何数量的用户都可以加入。

创建一个包含项目所有代码的文件夹。 导航到您刚刚在终端上创建的文件夹并运行 startproject命令来创建一个新的 Django 项目:

超过 20 万开发人员使用 LogRocket 来创造更好的数字体验 了解更多 →

$ django-admin startproject chat .

现在,运行 $ python3 manage.py startapp app创建一个新的应用程序。

您需要让您的 Django 项目知道已经添加了一个新应用程序并且您安装了 Channels 插件。 您可以通过更新 chat/settings.py文件并添加 ‘app’到 INSTALLED_APPS列表。 它看起来像下面的代码:

project/settings.py
INSTALLED_APPS = [
   ...

   'channels',
   'app',
]

在里面 settings.py文件,您应该设置配置以允许 Django 和 Django 通道通过消息代理相互连接。 为此,我们可以使用 Redis 之类的工具,但在此示例中,我们将坚持使用本地后端。 将以下代码行添加到您的 settings.py文件:

ASGI_APPLICATION = "chat.routing.application" #routing.py will handle the ASGI
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': "channels.layers.InMemoryChannelLayer"
        }
    }

在上面的代码中, ASGI_APPLICATION需要运行 ASGI 服务器并告诉 Django 在事件发生时该做什么。 我们将把这个配置放在一个名为 routing.py. 路由 Django Channels 类似于 Django URL 配置; 它选择将 WebSocket 请求发送到服务器时要运行的代码。

在您创建路由之前,我们将首先开发 消费者 。 在 Django Channels 中,消费者使您能够在代码中创建一组函数,这些函数将在事件发生时被调用。 它们类似于 views在姜戈中。

开发消费者,打开 app/文件夹,新建一个名为 consumers.py,并粘贴以下代码:

app/consumers.py
import json
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
​
class TextRoomConsumer(WebsocketConsumer):
    def connect(self):
​
        self.room_name = self.scope\['url_route'\]['kwargs']['room_name']
        self.room_group_name = 'chat_%s' % self.room_name
        # Join room group
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )
        self.accept()
    def disconnect(self, close_code):
        # Leave room group
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )
​
    def receive(self, text_data):
        # Receive message from WebSocket
        text_data_json = json.loads(text_data)
        text = text_data_json['text']
        sender = text_data_json['sender']
        # Send message to room group
        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': text,
                'sender': sender
            }
        )
​
    def chat_message(self, event):
        # Receive message from room group
        text = event['message']
        sender = event['sender']
        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'text': text,
            'sender': sender
        }))

现在,我们可以创建将处理您刚刚创建的消费者的路由。 创建一个名为的新文件 routing.py并粘贴下面的代码,这将协调消费者:

from channels.routing import ProtocolTypeRouter, URLRouter
import app.routing
from django.urls import re_path
from app.consumers import TextRoomConsumer
websocket_urlpatterns = [
    re_path(r'^ws/(?P[^/]+)/$', TextRoomConsumer.as_asgi()),
]
the websocket will open at 127.0.0.1:8000/ws/
application = ProtocolTypeRouter({
    'websocket':
        URLRouter(
            websocket_urlpatterns
        )
    ,
})

构建前端

现在,让我们构建一个聊天应用程序的前端,该应用程序使用 WebSockets 连接到 Django 后端。 我们将使用 React 构建这部分,并 使用 MUI 添加样式 。

在您的终端中,导航到项目的根目录并运行以下命令以获取 React 的 Create React App 样板代码:

npx create-react-app frontend

下一个, cd进入 frontend/目录并运行以下命令来安装 MUI 和 WebSocket 依赖项,这允许我们将 React 应用程序连接到 WebSocket 服务器:

npm install --save --legacy-peer-deps @material-ui/core
npm install websocket

删除所有代码 frontend/src/App.js. 我们将用本教程其余部分中的代码替换它,从初始状态开始:

import React, { Component } from 'react';
import { w3cwebsocket as W3CWebSocket } from "websocket";

class App extends Component {
  state = {
    filledForm: false,
    messages: [],
    value: '',
    name: '',
    room: 'test',
  }
  client = new W3CWebSocket('ws://127.0.0.1:8000/ws/' + this.state.room + '/'); //gets room_name from the state and connects to the backend server
  render(){
    }

}

现在,我们需要处理当组件安装在浏览器上时发生的事情。 我们希望应用程序连接到后端服务器并在组件挂载时获取消息,因此我们将使用 componentDidMount(). 您可以通过在 render()功能:

...

componentDidMount() {
    this.client.onopen = () => {
      console.log("WebSocket Client Connected");
    };
    this.client.onmessage = (message) => {
      const dataFromServer = JSON.parse(message.data);
      if (dataFromServer) {
        this.setState((state) => ({
          messages: [
            ...state.messages,
            {
              msg: dataFromServer.text,
              name: dataFromServer.sender,
            },
          ],
        }));
      }
    };
  }
render() {
...

接下来,我们将创建用于更新状态的表单。 我们将创建一个表单来更新 name发件人和房间名称。 然后,我们将创建另一个处理表单提交的表单。 将下面的代码粘贴到 render()功能:

  • 不要错过 The Replay 来自 LogRocket 的精选时事通讯
  • 了解 LogRocket 的 Galileo 如何消除噪音以主动解决应用程序中的问题
  • 使用 React 的 useEffect 优化应用程序的性能
  • 之间切换 在多个 Node 版本
  • 了解如何 使用 AnimXYZ 为您的 React 应用程序制作动画
  • 探索 Tauri ,一个用于构建二进制文件的新框架
  • 比较 NestJS 与 Express.js
render() {
    const { classes } = this.props;
    return (
      
        {this.state.filledForm ? (
          
Room Name: {this.state.room} {this.state.messages.map((message) => ( <> </> ))}
{ this.setState({ value: e.target.value }); this.value = this.state.value; }} />
) : (
this.setState({ filledForm: true })} > { this.setState({ room: e.target.value }); this.value = this.state.room; }} /> { this.setState({ name: e.target.value }); this.value = this.state.name; }} />
)}
); } export default withStyles(useStyles)(App);

当您填写房间名称和寄件人姓名时, filledForm将改为 true在该状态下,将呈现输入消息的表单。 在我们的代码中,我们使用了一些需要导入的 MUI 类。 您可以通过将以下代码粘贴到您的顶部 App.js文件:

import Button from "@material-ui/core/Button";
import CssBaseline from "@material-ui/core/CssBaseline";
import TextField from "@material-ui/core/TextField";
import Container from "@material-ui/core/Container";
import Card from "@material-ui/core/Card";
import CardHeader from "@material-ui/core/CardHeader";
import Paper from "@material-ui/core/Paper";
import { withStyles } from "@material-ui/core/styles";
const useStyles = (theme) => ({
  submit: {
    margin: theme.spacing(3, 0, 2),
  },
});

提交消息表单后,我们将在单击提交按钮时将文本发送到后端服务器。 将下面的代码直接粘贴到上面 componentDidMount()功能:

onButtonClicked = (e) => {
    this.client.send(
      JSON.stringify({
        type: "message",
        text: this.state.value,
        sender: this.state.name,
      })
    );
    this.state.value = "";
    e.preventDefault();
  };
  componentDidMount() {
...

测试应用程序

现在我们已经完成了应用程序的编码,我们可以对其进行测试。 首先,通过运行以下命令启动后端服务器。 确保您位于 manage.py文件是:

python manage.py runserver

在另一个终端窗口中,导航到 frontend/目录并通过运行以下命令来运行前端服务器。 React 应用程序将自动打开:

npm start

填写姓名和房间名称。 然后,在另一个名称不同但房间名称相同的浏览器中打开应用程序。 现在,您可以开始与自己聊天,您会注意到消息是实时收到的:

在本文中,我们了解了 WebSockets、它的应用程序以及如何通过利用 Django Channels 在 Django 中使用它。 最后,我们介绍了如何使用 React 建立与 Django 服务器的 WebSocket 连接。

尽管我们构建了一个高效的实时聊天应用程序,但您仍然可以进行改进。 例如,要存储消息,您可能会包含一个数据库连接。 作为本地后端的替代方案,您可以考虑使用 Redis 作为消息代理。

我希望您喜欢这篇文章,如果您有任何问题,请务必发表评论。 快乐编码!

全面了解生产 React 应用程序

调试 React 应用程序可能很困难,尤其是当用户遇到难以重现的问题时。 如果您对监控和跟踪 Redux 状态、自动显示 JavaScript 错误以及跟踪缓慢的网络请求和组件加载时间感兴趣,请 尝试 LogRocket 。

LogRocket 就像一个用于 Web 和移动应用程序的 DVR,几乎可以记录您的 React 应用程序上发生的所有事情。 无需猜测问题发生的原因,您可以汇总并报告问题发生时应用程序所处的状态。 LogRocket 还监控您的应用程序的性能,并使用客户端 CPU 负载、客户端内存使用情况等指标进行报告。

LogRocket Redux 中间件包为您的用户会话增加了一层额外的可见性。 LogRocket 记录来自 Redux 存储的所有操作和状态。

Original: https://blog.csdn.net/weixin_47967031/article/details/127122171
Author: pxr007
Title: 使用 React 和 Django Channels 构建聊天应用程序

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/733955/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Python x OpenCV+Numpy 函数参考列表

    (1)图像的读取操作cv2.imread(文件名,标记)功能:给定文件名和读入方式,读入一幅图像返回值:numpy数组,类型为ndarray的2维或3维数组文件名:图像全名,包括后…

    Python 2023年8月27日
    048
  • 猿创征文|数据导入与预处理-第2章-numpy

    数据导入与预处理-numpy 1.numpy介绍 2 数组对象 3 创建数组 * 3.1 根据现有数据类型创建数组 3.2 根据指定数值创建数组 3.3 根据指定数值范围创建数组 …

    Python 2023年8月23日
    042
  • dataframe批量替换值_Python之DataFrame按照规则批量修改某列的数据

    在使用Python进行数据分析时,我们经常会看一个数据的分布,然后对数据进行处理。比如说有一个场景: 以下数据是某个产品的提前预定期: import pandas as pd im…

    Python 2023年8月18日
    051
  • python+pytest+allure+jenkins搭建自动化测试框架

    1.框架目录(结构)1.1.common(公共模块)包括一些全局配置,读取系统/文件路径,日志,发送邮件,连接数据库等脚本日志模块: import logging import l…

    Python 2023年9月11日
    046
  • 使用matplotlib绘制散点图、条形图、直方图

    [ Matplotlib 是 Python 中常用的绘 图_库之一,可以用于 _绘制_各种类型的 _图_形。以下是 _Matplotlib 绘制_常见 _图_形的基本原理和设计说明…

    Python 2023年9月6日
    037
  • Numpy:读取本地文件及数据处理

    可以理解为方向,使用0,1,2…数字表示,对于一个一维数组,只有一个0轴,二维数组有0轴和1轴,三维数组有0,1,2轴,以此类推。(可以理解为数学中的x,y,z轴) 有…

    Python 2023年8月26日
    071
  • 千古前端图文教程-HTML002-浏览器的介绍

    浏览器的介绍 浏览器的介绍 常见的浏览器 浏览器的市场占有份额 浏览器的组成 + 1、渲染引擎(浏览器内核) 2、JS 引擎 浏览器工作原理 常见的浏览器 浏览器是网页运行的平台,…

    Python 2023年6月12日
    068
  • django学习__1

    Django python网络编程回顾 之前我们介绍过web应用程序和http协议,简单了解过web开发的概念。Web应用程序的本质 接收并解析HTTP请求,获取具体的请求信息 处…

    Python 2023年11月2日
    050
  • params传值一刷新就没了_【pytest】(十)fixture参数化-巧用params和ids优雅的创建测试数据…

    我们都知道参数化。 比如我要测试一个查询接口 /test/get_goods_list,这个接口可以查询到商品的信息。 在请求中,我可以根据请参数 goods_status的不同传…

    Python 2023年9月14日
    050
  • DjangoRestFramework使用总结

    你要去相信,没有到不了的明天。 摘要 本文主要描述DjangoRestFramework的相关内容,额外提及部分涉及到的其他知识。 简介 1.Django REST framewo…

    Python 2023年8月4日
    042
  • 驱动开发:内核监控FileObject文件回调

    本篇文章与上一篇文章 &#x300A;&#x9A71;&#x52A8;&#x5F00;&#x53D1;&#xFF1A;&#x…

    Python 2023年10月17日
    029
  • Matplotlib在figure中画矩形

    当您进行数据可视化时,您可能希望通过添加一些注释来突出显示绘图的特定区域。 在这篇文章中,我们将学习如何在 Python 中使用 matplotlib 制作的绘图上添加 &…

    Python 2023年8月31日
    042
  • PyCharm创建Scrapy项目

    Scrapy安装好之后我们便可以创建自己的第一个爬虫项目了。Scrapy安装可参考我的另一篇文章:https://mp.csdn.net/editor/html/115741881…

    Python 2023年10月1日
    060
  • 今天不写代码,聊聊热门的知识图谱

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处。 哈喽大家好啊,我是Hydra。 前一段时间,boss交给我个任务,让我调研一下知识图谱技术。虽说有点NLP的底子,不过研究起…

    Python 2023年10月22日
    044
  • Transformer学习资源&顺序推荐

    因为我个人不喜欢听一个老师重复讲而喜欢听多位老师讲同一个东西所以整理了一下这份清单,我觉得比我自己的学习顺序要好一些! 因为我个人不喜欢听一个老师重复讲而喜欢听多位老师讲同一个东西…

    Python 2023年10月28日
    033
  • Fatal error in launcher:解决

    报错目录 Fatal error in launcher: * 1.安装第三方库时 – 解决: 2.创建项目时 – 解决: 永久性解决:建议重新安装个稳定版…

    Python 2023年8月3日
    074
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球