Django中的实时通信:WebSockets与异步视图的结合【第167篇—实时通信】
👽发现宝藏
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。
在现代Web应用程序中,实时通信已经成为了必不可少的功能之一。无论是在线聊天、实时数据更新还是实时通知,都需要通过实时通信技术来实现。Django作为一个强大的Web框架,提供了许多工具来构建各种类型的Web应用程序,但是在实时通信方面,传统的请求-响应模式显然无法满足需求。在这篇文章中,我们将探讨如何利用Django中的WebSockets和异步视图来实现实时通信功能。
WebSockets简介
WebSockets是一种在单个TCP连接上提供全双工通信的协议。与HTTP请求-响应模式不同,WebSockets允许服务器和客户端之间进行持续的双向通信,从而实现了实时性。在Django中,我们可以使用第三方库django-channels
来实现WebSocket的支持。
异步视图
Django 3.1引入了异步视图的支持,使得我们可以编写异步处理请求的视图函数。这对于处理长时间运行的任务或需要等待外部资源响应的请求非常有用。
结合WebSockets与异步视图
下面我们将通过一个案例来演示如何在Django中结合WebSockets和异步视图来实现实时通信功能。假设我们正在开发一个简单的实时聊天应用。
安装依赖
首先,我们需要安装django-channels
库:
pip install channels
配置项目
在项目的settings.py
中,添加channels
应用:
INSTALLED_APPS = [...'channels',...
]
然后,创建一个名为routing.py
的新文件,在其中定义WebSocket路由:
# routing.pyfrom channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from django.urls import path
from myapp.consumers import ChatConsumerwebsocket_urlpatterns = [path('ws/chat/', ChatConsumer.as_asgi()),
]application = ProtocolTypeRouter({'websocket': AuthMiddlewareStack(URLRouter(websocket_urlpatterns)),
})
创建Consumer
接下来,我们创建一个消费者(Consumer)来处理WebSocket连接:
# consumers.pyimport json
from channels.generic.websocket import AsyncWebsocketConsumerclass 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.jsconst 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 = '';}
});
集成到模板
最后,我们在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的async
和await
语法来支持异步编程模式。异步视图允许在处理请求时挂起执行,等待IO操作完成而不会阻塞整个应用程序。
结合WebSockets与异步视图的优势
结合WebSockets与异步视图可以使得实时通信应用具备更高的性能和可扩展性。当有大量连接同时进行通信时,异步视图可以有效地管理这些连接,而不会因为一个连接的阻塞而影响其他连接的处理。这种方式下,应用程序能够更好地应对高并发情况,保持稳定性和高效性。
完善实时聊天应用
除了上述示例中的基本聊天功能之外,我们还可以对实时聊天应用进行一些扩展,比如:
- 用户认证:在连接WebSocket时进行用户认证,确保只有已登录的用户可以进入聊天室。
- 聊天室管理:创建多个聊天室,并允许用户选择加入不同的聊天室。
- 消息存储:将聊天记录保存到数据库中,以便用户在断线重连后可以查看历史消息。
- 消息通知:实现消息通知功能,当用户收到新消息时,通过浏览器通知或邮件提醒用户。
- 实时在线用户列表:显示当前在线用户列表,并在用户进入或离开聊天室时实时更新。
实时地理位置共享
假设我们正在开发一个实时地理位置共享应用,用户可以在地图上实时看到其他用户的位置。以下是一个简单的示例代码:
后端代码
# consumers.pyimport json
from channels.generic.websocket import AsyncWebsocketConsumerclass 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.jsconst 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.pyimport json
from channels.generic.websocket import AsyncWebsocketConsumerclass 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.jsconst 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图表库将实时数据实时展示在图表中。
这样的实时数据可视化功能可以应用在数据监控、实时分析等场景中,为用户提供实时的数据展示和监控功能。
高级功能和进阶应用
除了基本的实时聊天功能之外,结合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和异步视图的优势,并提供了一系列高级功能和进阶应用的示例,包括实时地理位置共享、实时数据可视化等。这些功能和应用可以为开发者提供更多的创新和可能性,从而满足不同场景下的实时通信需求。
相关文章:

Django中的实时通信:WebSockets与异步视图的结合【第167篇—实时通信】
👽发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在现代Web应用程序中,实时通信已经成为了必不可少的功能之一。无论是在线聊天、…...
R 格式(蓝桥杯)
文章目录 R 格式【问题描述】解题思路高精度乘法高精度加法 R 格式 【问题描述】 小蓝最近在研究一种浮点数的表示方法:R 格式。对于一个大于 0 的浮点数 d,可以用 R 格式的整数来表示。给定一个转换参数 n,将浮点数转换为 R格式整数的做法…...
Intellij idea的快速配置详细使用
IntelliJ IDEA是一款强大的集成开发环境(IDE),支持多种编程语言,包括Java、Kotlin、Scala等。以下是关于IntelliJ IDEA的快速配置和使用的详细步骤: 一、安装 前往IntelliJ IDEA的官方网站或可靠的软件下载平台&…...

JavaEE:JVM
基本介绍 JVM:Java虚拟机,用于解释执行Java字节码 jdk:Java开发工具包 jre:Java运行时环境 C语言将写入的程序直接编译成二进制的机器语言,而java不想重新编译,希望能直接执行。Java先通过javac把.java…...

Linux基础|线程池Part.1|线程池的定义和运行逻辑
线程池的定义和运行逻辑 多线程的问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。 那么一个很自然的想法就出现了…...
蓝队面试经验总结
Sql注入 1、sql注入漏洞原理 开发者没有在网页传参点做好过滤,导致恶意 sql 语句拼接到数据库进行执行 2、sql注入分类 联合注入 、布尔盲注 、时间盲注 、堆叠注入 、宽字节注入 、报错注入 3、堆叠注入原理 在 mysql 中,分号 代表一个查询语句的…...
MySQL命令分类与大纲
一、数据库管理 创建与删除数据库 CREATE DATABASE:创建新数据库DROP DATABASE:删除已存在的数据库ALTER DATABASE:修改数据库属性 切换与查看数据库 USE:选择当前工作数据库SHOW DATABASES:列出所有可用数据库 二、…...

windows编译xlnt,获取Excel表里的数据
用git拉取项目 这个文件是空的 要用git拉下来,使用终端编译xlnt库 点击解决方案 运行生成 然后新建项目,配置好库, #include <iostream> #include <xlnt/xlnt.hpp>int main() {// 打开 Excel 文件xlnt::workbook workbook;workb…...
c#字段和属性的区别
在C#中,字段(fields)和属性(properties)都是类的成员,它们提供了类存储数据的方式,但它们在用途和功能上有着明显的区别。 字段 字段通常用来存储类或结构的状态信息。字段是类的数据成员&…...

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

AI大模型日报#0416:李飞飞《2024年人工智能指数报告》、Sora加入Adobe、李彦宏聊百度大模型之路
导读: 欢迎阅读《AI大模型日报》,内容基于Python爬虫和LLM自动生成。目前采用“文心一言”生成了每条资讯的摘要。标题: 刚刚,李飞飞团队发布《2024年人工智能指数报告》:10大趋势,揭示AI大模型的“喜”与“忧” 摘…...

OpenCV轻松入门(八)——图片卷积
对图像和滤波矩阵进行逐个元素相乘再求和的操作就相当于将一个二维的函数移动到另一个二维函数的所有位置,这个操作就叫卷积。 卷积需要4个嵌套循环,所以它并不快,除非我们使用很小的卷积核。这里一般使用3x3或者5x5 图像滤波 图像滤波是尽…...
鸿蒙HarmonyOS开发规范-完善中
代码规范 所有文件,包括自动生成的编译文件package.json都要格式化(IDE快捷键CtrlAltL);函数命名,C大驼峰,TS、JS小驼峰,函数命名注意动宾结构;静态常量需使用全大写,文…...

神经网络压缩图像
简介 典型的压缩管道由四个组件组成: 编码:输入图像 x x x通过编码器函数 ε \varepsilon ε,将其转换为潜在表示 z z z。 量化:截断 z z z以丢弃一些不重要的信息 熵编码:使用某种形式的熵编码(例如&…...
Catagory(rt)
继承(IMP融合):支持super命令码;继承推荐重写 分类(IMP替换):不支持super命令码;分类推荐组合 //替换(原来没了/破坏掉原来IMP/分类(替换特性)) 情况1: 自封装(组件化)开源库>分类推荐组合 情况2:逆向分析> 有意替换>分类IMP替换 #import "CatagoryViewContro…...

Games104 现代游戏引擎3
Sprite Animation 序列帧动画 自由度(degrees of freedom,DoF)对于刚体而言描述它的运动需要3个位移3个旋转,一共6个自由度 顶点动画(per-vertex animation)利用网格的顶点来控制运动。此时网格上的每个顶…...

【云计算】混合云分类
《混合云》系列,共包含以下 3 篇文章: 【云计算】混合云概述【云计算】混合云分类【云计算】混合云组成、应用场景、风险挑战 😊 如果您觉得这篇文章有用 ✔️ 的话,请给博主一个一键三连 🚀🚀Ὠ…...

探索分布式系统监控zabbix------------自动发现与自动注册
目录 一、部署 zabbix 服务端 二、部署 zabbix 客户端 2.1环境准备 2.2服务端和客户端都配置时间同步 (ntp) 2.2.1服务端zbx-server 2.2.2服务端zabbix-agent01客户端 2.3客户端配置时区,与服务器保持一致 2.4设置 zabbix 的下载源&…...

权限管理Ranger详解
文章目录 一、Ranger概述与安装1、Ranger概述1.1 Ranger介绍1.2 Ranger的目标1.3 Ranger支持的框架1.4 Ranger的架构1.5 Ranger的工作原理 2、Ranger安装2.1 创建系统用户和Kerberos主体2.2 数据库环境准备2.3 安装RangerAdmin2.4 启动RangerAdmin 二、Ranger简单使用1、安装 R…...

WPF Extended.Wpf.Toolkit 加载界面
1、NuGet 中安装 Extended.Wpf.Toolkit 。 2、在MainWindow.xaml中添加xmlns:tk"http://schemas.xceed.com/wpf/xaml/toolkit" 。 MainWindow.xaml 代码如下。 <Window x:Class"WPF_Extended_Wpf_Toolkit_Loading.MainWindow" xmlns"ht…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...