Django中的实时通信:WebSockets与异步视图的结合

👽发现宝藏

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

在现代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.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 = '';}
});

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.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图表库将实时数据实时展示在图表中。

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

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.mzph.cn/web/2656.shtml

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

相关文章

光纤、以太网电缆和 DSL 的比较:技术指南

了解光纤、以太网电缆和 DSL 之间的差异对于做出有关互联网连接的明智决策至关重要。本技术指南对这些技术进行了全面比较&#xff0c;讨论了它们的独特功能、性能指标和应用。它旨在为您提供必要的知识&#xff0c;以选择最适合您的特定需求的选项。 光纤、以太网电缆和 DSL …

【网络编程】网络编程中的基本概念及Java实现UDP、TCP客户端服务器程序(万字博文)

系列文章目录 【网络通信基础】网络中的常见基本概念 【网络编程】网络编程中的基本概念及Java实现UDP、TCP客户端服务器程序&#xff08;万字博文&#xff09; 【网络原理】UDP协议的报文结构 及 校验和字段的错误检测机制&#xff08;CRC算法、MD5算法&#xff09; 目录 …

【C++】优先队列

优先队结构的不同物理结构与常用操作算法 优先队列是一种特殊的队列,队列中的元素具有优先级,每次弹出操作会弹出优先级最高的元素。 优先队列常用的物理结构有: 1. 数组:简单但不高效,插入和删除操作需要移动大量元素,时间复杂度高。 2. 二叉堆:是一种完全二叉树,通常用数…

Nacos采坑:非集群Nacos不要使用同一个MySQL数据库

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Nacos 致力于帮助您…

【Linux】使用Jenkins + svn + springboot自动构建jar包并自动打包在服务器上运行

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

面包屑新玩法,ReactRouter+Ant Design实现动态渲染

在Ant Design中,可以通过Breadcrumb组件结合react-router库实现动态生成面包屑导航。具体步骤如下: 定义路由配置数据结构 我们需要在路由配置中添加额外的面包屑相关信息,例如面包屑标题、icon等。例如: const routes [{path: /,breadcrumbName: 首页},{path: /users,brea…

remote: HTTP Basic: Access deniedfatal: Authentication failed for

$ git push -u origin main remote: HTTP Basic: Access denied fatal: Authentication failed for https://gitcode.com/edenl/GD32E350_hid_keyboard.git/ 使用访问令牌做为密码登录即可。

拼多多面试题——力扣版测试用例纠错

最近我看到力扣上这个题目&#xff0c;用了三种方法&#xff0c;结果没有一种正确&#xff0c;我就纳闷儿了&#xff0c;为何总有一个测试用例过不了&#xff0c;结果我发现这个测试用例确实有问题啊。。。。。 题目&#xff1a; 表&#xff1a;Logs ----------------------…

LeetCode_链表的回文结构

✨✨所属专栏&#xff1a;LeetCode刷题专栏✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 题目描述&#xff1a; 对于一个链表&#xff0c;请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法&#xff0c;判断其是否为回文结构。给定一个链表的头指针A&#xff0c;请返回一个bo…

JS----前端不同格式的 UUID生成

前端 UUID生成 export const generateUUID () > {let timestamp new Date().getTime()let performanceNow (typeof performance ! undefined && performance.now && performance.now() * 1000) || 0return xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx.replac…

基于智能推荐的校园兼职招聘平台

3协同过滤算法简介 目前&#xff0c;推荐算法有很多种&#xff0c;可以应用于日常生活的许多领域&#xff0c;对大量数据进行处理和分析&#xff0c;然后进行分类。它将显示用户可能感兴趣的内容&#xff0c;这是推荐算法的主要功能之一[1]。 协同过滤算法通常包括两类&#…

详解数据结构:栈

一、顺序栈 顺序栈的存储方式如下&#xff1a; 从图中可以看出&#xff0c;顺序栈需要两个指针&#xff0c;base指向栈底&#xff0c;top指向栈顶。 typedef struct SqStack {ElemType *base; //栈底指针ElemType *top; //栈顶指针}SqStack; 说明&#xff1a; ElemType是元…

【智能算法】水循环算法(WCA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2012年&#xff0c;H Eskandar等人受到自然水循环过程启发&#xff0c;提出了水循环算法&#xff08;Water Cycle Algorithm, WCA&#xff09;。 2.算法原理 2.1算法思想 WCA模拟了大自然水循环过…

稳态视觉诱发电位 (SSVEP) 分类学习系列 (1) :FFT-CNN-CCA

稳态视觉诱发电位分类学习系列:FFT-CNN-CCA 0. 引言1. 主要贡献2. 提出的方法2.1 数据处理2.2 卷积神经网络的结构 3. 结果3.1 健康参与者结果比较3.2 卒中患者结果比较 4. 总结欢迎来稿 论文地址&#xff1a;https://ieeexplore.ieee.org/document/8708243 论文题目&#xff1…

日志分析简单总结

1、分析日志的目的 误报&#xff1a;不是攻击而上报成攻击 漏报&#xff1a;是攻击而没有防御的情况 日志分析可以判断是否误判或者漏判&#xff0c;可以溯源攻击行为 在护网作为防守方必备的技能&#xff08;分析NGAF和态势感知&#xff0c;发现异常&#xff09; 2、攻击出现…

探索比特币符文热:市场趋势与持续性分析

在加密货币世界中&#xff0c;比特币一直是备受关注的焦点之一。然而&#xff0c;近年来&#xff0c;随着DeFi&#xff08;去中心化金融&#xff09;的兴起&#xff0c;一种新的潮流开始崭露头角——比特币符文。本文将探讨比特币符文的兴起&#xff0c;分析市场趋势&#xff0…

iOS 17上如何恢复数据?iOS 17 数据恢复软件

“您好&#xff0c;我正在为我的 iPhone 寻找一款iOS 17 数据恢复软件。升级到 iOS 17 后&#xff0c;我丢失了 iPhone 上的所有照片、联系人和消息。有什么建议吗&#xff1f;” ——丹尼 iOS 17数据恢复软件下载 升级到iOS 17后如何恢复丢失的数据&#xff1f;由于在 iPhone…

聊聊 Linux iowait

哈喽大家好&#xff0c;我是咸鱼。 我们在使用 top 命令来查看 Linux 系统整体 CPU 使用情况的时候&#xff0c;往往看的是下面这一列&#xff1a; %Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 68.0 wa, 0.0 hi, 0.0 si, 0.0 st其中&#xff0c;man 手册解释 wa 表示 …

异地组网、内部网络需求同时满足,贝锐企业路由器G300开箱体验

由于公司最近新增了办事处&#xff0c;作为IT管理员的我不仅需要搞定办事处的网络&#xff0c;还需要解决远程访问公司内部办公系统以及文件存储服务器的问题。 在此之前&#xff0c;只有少量人员出差时&#xff0c;我们采用了虚拟专网方案来进行远程访问。然而&#xff0c;新…

深度学习基础之《TensorFlow框架(15)—神经网络》

一、神经网络基础 1、什么是神经网络 人工神经网络&#xff08;Artificial Neural Network&#xff0c;简写为ANN&#xff09;。也简称为神经网络&#xff08;NN&#xff09; 是一种模仿生物神经网络&#xff08;动物的中枢神经系统&#xff0c;特别是大脑&#xff09;结构和功…