Django中的实时通信:WebSockets与异步视图的结合【第167篇—实时通信】

news2025/1/25 9:14:08

👽发现宝藏

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。

在现代Web应用程序中,实时通信已经成为了必不可少的功能之一。无论是在线聊天、实时数据更新还是实时通知,都需要通过实时通信技术来实现。Django作为一个强大的Web框架,提供了许多工具来构建各种类型的Web应用程序,但是在实时通信方面,传统的请求-响应模式显然无法满足需求。在这篇文章中,我们将探讨如何利用Django中的WebSockets和异步视图来实现实时通信功能。

WebSockets简介

WebSockets是一种在单个TCP连接上提供全双工通信的协议。与HTTP请求-响应模式不同,WebSockets允许服务器和客户端之间进行持续的双向通信,从而实现了实时性。在Django中,我们可以使用第三方库django-channels来实现WebSocket的支持。

image-20240330143213129

异步视图

Django 3.1引入了异步视图的支持,使得我们可以编写异步处理请求的视图函数。这对于处理长时间运行的任务或需要等待外部资源响应的请求非常有用。

结合WebSockets与异步视图

下面我们将通过一个案例来演示如何在Django中结合WebSockets和异步视图来实现实时通信功能。假设我们正在开发一个简单的实时聊天应用。

安装依赖

首先,我们需要安装django-channels库:

pip install channels

配置项目

在项目的settings.py中,添加channels应用:

INSTALLED_APPS = [
    ...
    'channels',
    ...
]

然后,创建一个名为routing.py的新文件,在其中定义WebSocket路由:

# routing.py

from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from django.urls import path
from myapp.consumers import ChatConsumer

websocket_urlpatterns = [
    path('ws/chat/', ChatConsumer.as_asgi()),
]

application = ProtocolTypeRouter({
    'websocket': AuthMiddlewareStack(
        URLRouter(
            websocket_urlpatterns
        )
    ),
})

创建Consumer

接下来,我们创建一个消费者(Consumer)来处理WebSocket连接:

# consumers.py

import json
from channels.generic.websocket import AsyncWebsocketConsumer

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = 'chat_room'
        self.room_group_name = f'chat_{self.room_name}'

        # 加入聊天室群组
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        # 离开聊天室群组
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        # 发送消息到聊天室群组
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )

    async def chat_message(self, event):
        message = event['message']

        # 发送消息给WebSocket连接
        await self.send(text_data=json.dumps({
            'message': message
        }))

编写前端代码

在前端页面中,我们需要使用JavaScript来连接WebSocket并处理消息的发送和接收:

// chat.js

const chatSocket = new WebSocket('ws://localhost:8000/ws/chat/');

chatSocket.onmessage = function(e) {
    const data = JSON.parse(e.data);
    const message = data['message'];
    // 处理收到的消息
    console.log(message);
};

chatSocket.onclose = function(e) {
    console.error('Chat socket closed unexpectedly');
};

document.querySelector('#chat-message-input').addEventListener('keypress', function(e) {
    if (e.key === 'Enter') {
        const messageInputDom = document.querySelector('#chat-message-input');
        const message = messageInputDom.value;
        chatSocket.send(JSON.stringify({
            'message': message
        }));
        messageInputDom.value = '';
    }
});

image-20240330143127425

集成到模板

最后,我们在Django模板中集成JavaScript代码:

<!-- chat.html -->

<!DOCTYPE html>
<html>
<head>
    <title>Chat</title>
</head>
<body>
    <textarea id="chat-message-input"></textarea>
    <script src="{% static 'chat.js' %}"></script>
</body>
</html>

引入异步视图

在Django 3.1之前,视图函数都是同步执行的,这意味着一个视图函数中的代码会一直执行直到返回一个HTTP响应给客户端。然而,有些任务可能是耗时的,比如调用外部API或者执行复杂的计算。在这种情况下,同步视图会阻塞整个应用程序,导致性能下降。

为了解决这个问题,Django引入了异步视图,它们使用Python的asyncawait语法来支持异步编程模式。异步视图允许在处理请求时挂起执行,等待IO操作完成而不会阻塞整个应用程序。

结合WebSockets与异步视图的优势

结合WebSockets与异步视图可以使得实时通信应用具备更高的性能和可扩展性。当有大量连接同时进行通信时,异步视图可以有效地管理这些连接,而不会因为一个连接的阻塞而影响其他连接的处理。这种方式下,应用程序能够更好地应对高并发情况,保持稳定性和高效性。

image-20240330143335659

完善实时聊天应用

除了上述示例中的基本聊天功能之外,我们还可以对实时聊天应用进行一些扩展,比如:

  1. 用户认证:在连接WebSocket时进行用户认证,确保只有已登录的用户可以进入聊天室。
  2. 聊天室管理:创建多个聊天室,并允许用户选择加入不同的聊天室。
  3. 消息存储:将聊天记录保存到数据库中,以便用户在断线重连后可以查看历史消息。
  4. 消息通知:实现消息通知功能,当用户收到新消息时,通过浏览器通知或邮件提醒用户。
  5. 实时在线用户列表:显示当前在线用户列表,并在用户进入或离开聊天室时实时更新。

实时地理位置共享

假设我们正在开发一个实时地理位置共享应用,用户可以在地图上实时看到其他用户的位置。以下是一个简单的示例代码:

后端代码
# consumers.py

import json
from channels.generic.websocket import AsyncWebsocketConsumer

class LocationConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = 'location_room'
        self.room_group_name = f'location_{self.room_name}'

        # 加入地理位置共享房间
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        # 离开地理位置共享房间
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        latitude = text_data_json['latitude']
        longitude = text_data_json['longitude']

        # 发送位置信息到地理位置共享房间
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'location_message',
                'latitude': latitude,
                'longitude': longitude
            }
        )

    async def location_message(self, event):
        latitude = event['latitude']
        longitude = event['longitude']

        # 发送位置信息给WebSocket连接
        await self.send(text_data=json.dumps({
            'latitude': latitude,
            'longitude': longitude
        }))
前端代码
// location.js

const locationSocket = new WebSocket('ws://localhost:8000/ws/location/');

locationSocket.onmessage = function(e) {
    const data = JSON.parse(e.data);
    const latitude = data['latitude'];
    const longitude = data['longitude'];
    // 在地图上显示用户位置
    updateMap(latitude, longitude);
};

locationSocket.onclose = function(e) {
    console.error('Location socket closed unexpectedly');
};

function sendLocation(latitude, longitude) {
    locationSocket.send(JSON.stringify({
        'latitude': latitude,
        'longitude': longitude
    }));
}

在这个示例中,用户通过前端界面在地图上选择或移动位置,然后通过WebSocket发送位置信息到服务器。服务器接收到位置信息后,将其广播给所有连接的用户,前端界面接收到位置信息后,在地图上实时更新其他用户的位置。

这样的实时地理位置共享功能可以应用在社交应用、实时导航应用等场景中,为用户提供更好的交互体验。

实时数据可视化

假设我们有一个数据监控系统,需要实时展示各种传感器的数据。以下是一个简单的示例代码:

后端代码
# consumers.py

import json
from channels.generic.websocket import AsyncWebsocketConsumer

class SensorDataConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = 'sensor_data_room'
        self.room_group_name = f'sensor_data_{self.room_name}'

        # 加入传感器数据共享房间
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        # 离开传感器数据共享房间
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        sensor_id = text_data_json['sensor_id']
        sensor_value = text_data_json['sensor_value']

        # 发送传感器数据到传感器数据共享房间
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'sensor_data_message',
                'sensor_id': sensor_id,
                'sensor_value': sensor_value
            }
        )

    async def sensor_data_message(self, event):
        sensor_id = event['sensor_id']
        sensor_value = event['sensor_value']

        # 发送传感器数据给WebSocket连接
        await self.send(text_data=json.dumps({
            'sensor_id': sensor_id,
            'sensor_value': sensor_value
        }))
前端代码
// sensor_data.js

const sensorDataSocket = new WebSocket('ws://localhost:8000/ws/sensor_data/');

sensorDataSocket.onmessage = function(e) {
    const data = JSON.parse(e.data);
    const sensorId = data['sensor_id'];
    const sensorValue = data['sensor_value'];
    // 更新传感器数据图表
    updateChart(sensorId, sensorValue);
};

sensorDataSocket.onclose = function(e) {
    console.error('Sensor data socket closed unexpectedly');
};

function sendSensorData(sensorId, sensorValue) {
    sensorDataSocket.send(JSON.stringify({
        'sensor_id': sensorId,
        'sensor_value': sensorValue
    }));
}

在这个示例中,传感器设备通过WebSocket将实时数据发送到服务器,服务器接收到数据后将其广播给所有连接的用户,前端界面接收到数据后,使用JavaScript图表库将实时数据实时展示在图表中。

这样的实时数据可视化功能可以应用在数据监控、实时分析等场景中,为用户提供实时的数据展示和监控功能。

image-20240330143414954

高级功能和进阶应用

除了基本的实时聊天功能之外,结合WebSockets和异步视图还可以实现一系列高级功能和进阶应用。以下是一些示例:

1. 实时地理位置共享

利用WebSocket和异步视图,可以实现用户之间实时的地理位置共享。当用户移动时,前端应用可以将用户的位置信息发送到服务器,服务器再将这些信息广播给其他用户。这种功能在社交应用、地图导航应用等场景中非常有用。

2. 实时数据可视化

在数据分析和监控领域,实时数据可视化是一项重要的任务。通过WebSocket和异步视图,可以实时将数据传输到前端,并利用JavaScript图表库(如Highcharts、Chart.js等)实时展示数据变化趋势、实时监控系统状态等。

3. 在线协作编辑

利用WebSocket和异步视图,可以实现多人在线协作编辑功能,类似于Google Docs。当一个用户编辑文档时,其余用户可以实时看到编辑内容的变化,从而实现多人实时协作编辑。

4. 实时游戏

实时游戏对于实时通信的需求非常高。结合WebSocket和异步视图,可以实现实时的多人在线游戏,比如棋牌游戏、实时战略游戏等,提供流畅的游戏体验。

5. 实时搜索和过滤

在网站和应用中,用户可能需要实时搜索和过滤数据。通过WebSocket和异步视图,可以实时向服务器发送搜索关键词或过滤条件,并实时获取服务器返回的搜索结果或过滤后的数据,从而提高用户体验。

6. 实时投票和问卷调查

在线投票和问卷调查通常需要实时获取投票结果或问卷填写情况。结合WebSocket和异步视图,可以实时更新投票结果图表或问卷统计数据,让用户实时了解当前的投票情况或问卷填写进度。

总结

本文介绍了如何利用Django中的WebSockets和异步视图来实现实时通信功能。我们首先了解了WebSockets的基本概念和工作原理,以及Django中使用django-channels库来支持WebSockets的方法。接着,我们深入探讨了异步视图的概念和用法,以及如何结合WebSockets和异步视图来实现实时通信功能。

通过一个简单的实时聊天应用的示例,我们演示了如何创建WebSocket消费者(Consumer)来处理WebSocket连接,并利用异步视图来处理WebSocket连接中的事件。我们还介绍了如何在前端页面中使用JavaScript来连接WebSocket,并实时处理接收到的消息。

随后,我们进一步探讨了结合WebSockets和异步视图的优势,并提供了一系列高级功能和进阶应用的示例,包括实时地理位置共享、实时数据可视化等。这些功能和应用可以为开发者提供更多的创新和可能性,从而满足不同场景下的实时通信需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1600614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

云计算: OVN 集群 部署分布式交换机

目录 一、实验 1.环境 2.OVN 集群 部署云主机 3.中心端添加DVS分布式大二层交换机 二、问题 1.南向控制器查看主机名只显示localhost 2.中心端如何添加DVR分布式⼤三层路由器 一、实验 1.环境 (1) 主机 表1 宿主机 主机架构软件主要服务IP备注ovn_central中心端 ovn…

Unity 点击次数统计功能

介绍 &#x1f4a1;.调用方便&#xff0c;发生点击事件后直接通过"xxx".CacheClick缓存 &#x1f4a1;. 在允许的时间间隔内再次点击会累计点击次数&#xff0c;直到超出后触发事件 传送门&#x1f448;

WebLogic 数据源连接泄露

编码时&#xff0c;有时会忘记释放使用的数据源连接&#xff0c;造成连接泄露&#xff0c;没有连接资源可用。 现象 java.sql.SQLException: Cannot obtain XAConnectionat weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1691)at weblogic.jdbc.jta.…

汉字编码实验

Logisim的简介和安装 首先要知道什么是logisim? Logisim是一种用于数字电路设计和模拟的开源工具&#xff0c;Logisim在2014年10月11日无限期暂停。因它足够简单&#xff0c;可以帮助学习逻辑电路相关的基本概念而闻名。Logisim被世界各地大学的学生在课程中使用。 Logisim的…

有回显命令执行-命令拼接+关键字绕过

[题目信息]&#xff1a; 题目名称题目难度有回显命令执行-命令拼接&#xff08;训练题&#xff09;2 [题目考点]&#xff1a; 远程命令执行漏洞&#xff0c;用户通过浏览器提交执行命令&#xff0c;由于服务器端没有针对执行函数做过滤&#xff0c;导致在没有指定绝对路径的…

快速切换node.js版本方法(使用开源项目方便切换版本)

1、安装nvm nvm下载地址&#xff1a;https://github.com/coreybutler/nvm-windows/ 2、输入nvm -v 3、查看可以安装的node.js版本 4、安装你想要的版本 5、查看是否安装成功&#xff08;*表示目前你使用的版本&#xff09; 6、切换版本 7、查询当前使用的版本

使用docker配置DSP-SLAM

一.Docker环境配置 1.简单介绍 –docker容器技术–。 简单理解&#xff1a;Anaconda用于隔离不同的python环境&#xff1b;docker可以理解成在你的机器里面安装了一个独立的系统&#xff0c;因此它可以隔离不同的CUDA环境&#xff0c;还有着独立的文件系统&#xff0c;防止别…

Matlab方程组拟合【案例源码+视频教程】

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《复杂函数拟合案例分享》本专栏旨在提供 1.以案例的形式讲解各类复杂函数拟合的程序实现方法&#xff0c;并提供所有案例完整源码&#xff1b;2.…

记一次Mysql数据库宕机This could be because you hit a bug.

Hi I’m Shendi 今天收到消息说所有软件不能用了&#xff0c;网页都打不开&#xff0c;遇到了问题&#xff0c;于是在这里记录一下 记一次Mysql数据库宕机This could be because you hit a bug. 起因 为了节省成本&#xff0c;对于小公司而言服务器数量通常不会太多&#xff…

HTTP协议安全传输教程

HTTP协议有多个版本&#xff0c;包括但不限于HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2和HTTP/3。这些版本各自具有不同的特点和改进&#xff0c;以适应网络技术的发展和满足不同的需求。例如&#xff0c;HTTP/1.0使用文本格式传输数据&#xff0c;简单易用且兼容性好&#xff0c;…

OpenCV基本图像处理操作(六)——直方图与模版匹配

直方图 cv2.calcHist(images,channels,mask,histSize,ranges) images: 原图像图像格式为 uint8 或 float32。当传入函数时应 用中括号 [] 括来例如[img]channels: 同样用中括号括来它会告函数我们统幅图 像的直方图。如果入图像是灰度图它的值就是 [0]如果是彩色图像 的传入的…

热门动画插件DoTween的使用

热门动画插件DoTween的使用 做游戏基本都会用到插件&#xff0c;它能让你的效率更高&#xff0c;因为它里面都是写好了的方法&#xff0c;只要用就可以了。在众多动画插件中&#xff0c;DoTween脱颖而出&#xff0c;因为它用起来很简单也很方便&#xff0c;自然用的人就多了。…

计算机视觉动作识别——YOWO用于实时时空动作定位与识别的算法解析

摘要 时空动作定位要求将两种信息源整合到设计的架构中&#xff1a;(1) 来自先前帧的时间信息和(2) 来自关键帧的空间信息。当前的最先进方法通常使用单独的网络提取这些信息&#xff0c;并使用额外的机制进行融合以获得检测结果。YOWO是一个用于视频流中实时时空动作定位的统…

软件杯 深度学习图像修复算法 - opencv python 机器视觉

文章目录 0 前言2 什么是图像内容填充修复3 原理分析3.1 第一步&#xff1a;将图像理解为一个概率分布的样本3.2 补全图像 3.3 快速生成假图像3.4 生成对抗网络(Generative Adversarial Net, GAN) 的架构3.5 使用G(z)生成伪图像 4 在Tensorflow上构建DCGANs最后 0 前言 &#…

解剖this指针

目录 this指针的理解 1. this指针的用处 2.this指针的使用 3.this指针的使用 this指针来源 this指针的理解 通常在class定义时要用到类型变量自身时&#xff0c;因为这时候还不知道变量名&#xff08;为了通用也不可能固定实际的变量名&#xff09;&#xff0c;就用this这样…

【前端】1. HTML【万字长文】

HTML 基础 HTML 结构 认识 HTML 标签 HTML 代码是由 “标签” 构成的. 形如: <body>hello</body>标签名 (body) 放到 < > 中大部分标签成对出现. <body> 为开始标签, </body> 为结束标签.少数标签只有开始标签, 称为 “单标签”.开始标签和…

微软正式发布Copilot for Security

微软公司近日宣布&#xff0c;其备受期待的安全自动化解决方案——Copilot for Security现已全面上市&#xff0c;面向全球用户开放。这一创新工具的推出标志着微软在提升企业安全防护能力方面迈出了重要一步&#xff0c;同时也为安全专业人士提供了强大的支持。 Copilot for …

深入理解插入排序:直接插入排序与希尔排序

文章目录 深入理解插入排序&#xff1a;直接插入排序与希尔排序直接插入排序算法描述工作原理性能分析 希尔排序算法描述实现代码性能分析 比较直接插入排序与希尔排序结论 深入理解插入排序&#xff1a;直接插入排序与希尔排序 排序算法是计算机科学中的基石之一&#xff0c;…

【芯片介绍】中微半导高性能车规级MCU BAT32A233

中微半导体&#xff08;深圳&#xff09;股份有限公司已推出车规MCU新品——BAT32A233&#xff0c;该产品具有小资源、高性能、支持硬件LIN2.2接口的性能优势&#xff0c;非常适合汽车的门、窗、灯、传感器、控制面板、组合开关等小巧、灵活的部件应用场景。 BAT32A233基于Ar…

无线网络安全之WiFi Pineapple初探

背景 WiFi Pineapple&#xff08;大菠萝&#xff09;是由国外无线安全审计公司Hak5开发并售卖的一款无线安全测试神器。集合了一些功能强大的模块&#xff0c;基本可以还原钓鱼攻击的全过程。在学习无线安全时也是一个不错的工具&#xff0c;本文主要讲WiFi Pineapple基础配置…