Django3框架-(3)-[使用websocket]:使用channels实现websocket功能;简化的配置和实际使用方式
概述:
对于Django使用channels实现websocket的功能,之前就写了几篇博文了。随着在项目的使用和实际维护来说,重新设置了相关处理方法。
一般来说,前后端都只维护一个全局的连接,通过携带数据来判断具体的操作,大致的业务逻辑(非群聊功能):
1、前端主动发起连接,发送了数据给后端,后端获取到数据后,解析出前端需要的是啥数据,查询出数据,返回给前端。(一次请求一次返回了)
2、部分数据变化了,后端需要主动告知前端,让前端重新查询对应的数据。(实时更新数据)
一、依赖
python=3.9.0
包:
pip install channels==3.0.0
pip install daphne==3.0.2
pip install redis==4.6.0
pip install channels-redis=3.1.0django-cors-headers==3.5.0
项目结构:
项目名
-
apps
-
user
-
websocket
-
routings.py
-
consumers.py
-
update.py
-
send_date.py
-
__init__.py
-
-
-
项目名
-
settings.py
-
asgi.py
-
urls.py
-
wsgi.py
-
__init__.py
-
-
manage.py
二、settings.py设置
#注册channels
INSTALLED_APPS = [...'channels', # django通过其实现websocket
]WSGI_APPLICATION = 'HeartFailure.wsgi.application'#channels使用需要添加ASGI_APPLICATION
ASGI_APPLICATION = 'HeartFailure.asgi.application'#使用channel_layers需要配置通道
CHANNEL_LAYERS = {"default": {#1、使用内存作为通道(开发使用)"BACKEND": "channels.layers.InMemoryChannelLayer",#2、使用redis(上线使用)# 'BACKEND': 'channels.layers.RedisChannelLayer',# 'CONFIG': {# 'hosts': [('localhost', 6379)],# },}
}#####1、 cors资源跨域共享配置
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = ('DELETE','GET','OPTIONS','PATCH','POST','PUT','VIEW',
)CORS_ALLOW_HEADERS = ('XMLHttpRequest','X_FILENAME','accept-encoding','authorization','content-type','dnt','origin','user-agent','x-csrftoken','x-requested-with','Pragma','token' #请求头允许自定义的字符串
)
三、创建websocket包
概述:将所有的wesocket相关的请求都放到一个包,集中管理。
websocket包下创建:
-
routings.py
-
存放websocket请求相关的路由信息
-
-
consumers.py
-
存放websocket请求处理的类
-
-
update.py
-
数据变化时,服务器主动通知前端更新数据
-
-
send_data.py
-
前端发起请求时,返回的数据
-
1、consumers.py
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
from asgiref.sync import async_to_sync
import time
import json
# 接收到前端的websocket请求,直接向单个发送需要数据
from apps.websocket.send_data import base_sendclass AllDataConsumers(WebsocketConsumer):# 统一的房间名room_name = 'chat_all_data'def connect(self):cls = AllDataConsumersself.room_group_name = cls.room_name# 加入到房间组内, self.channel_name是当前async_to_sync(self.channel_layer.group_add)(self.room_group_name, self.channel_name)headers = self.scope['headers']print(headers)token = Nonefor key, value in headers:if key == b'token':token = value.decode('utf-8')print(token)# 同意创建连接self.accept()def disconnect(self, close_code):print('有浏览器退出了websocket!!!!')# Leave room groupasync_to_sync(self.channel_layer.group_discard)(self.room_group_name, self.channel_name)# Receive message from WebSocketdef receive(self, text_data=None, bytes_data=None):''':param text_data: 接收字符串类型的数据:param bytes_data: 接收bytes类型的数据:return:如果是浏览器直接请求时,就单独给这个浏览器返回结果,无需给房间组内的发送数据'''try:text_data_json = json.loads(text_data)the_type = text_data_json.get('type', 'none')except Exception as e:self.send(json.dumps({'code': 400, 'msg': '传递的数据请按照{"type":"xx","id":x,"params":{}}格式'}, ensure_ascii=False))self.disconnect(400)return#1、前端主动请求websocket时,拿到对应的数据,单独给该websocket返回数据send_data = base_send(text_data_json)if isinstance(send_data,dict):#需要给请求的前端返回数据self.send(json.dumps(send_data, ensure_ascii=False))else:#无需给请求的前端返回数据pass# 2、将数据发送到房间组内 (在非聊天模式无需这样操作)# async_to_sync(self.channel_layer.group_send)(# self.room_group_name, {'type':'send_to_chrome','data':send_data}# )'''参数说明:self.room_group, 给哪个房间组发送数据,{'type':'send_to_chrome','data':send_data}send_to_chrome 是处理函数,在这里负责将房间组内的数据发送给浏览器send_data 要发送的数据'''# 自定义的处理房间组内的数据:实时推送就是使用这个来实现的def send_to_chrome(self, event):try:data = event.get('data')# 接收房间组广播数据,将数据发送给websocketself.send(json.dumps(data, ensure_ascii=False))except Exception as e:print('给全局的websocket推送消息失败')
2、send_data.py
def base_send(data:dict):'''功能:发起websocket请求时,给当前websocket返回数据:param data: {'type':'要操作的数据类型','id':'有id就是指定每个数据','params':{'page':'页码','page_size':'页面大小', }}:return:'''the_type = data.get('type')id = data.get('id')send_data = {'type':the_type,'data':'返回的数据'}#用户管理-搜索功能,用户信息是实时更新的if the_type == 'search_user_data':#前端发起websocket请求时,此类型时,无需返回数据return send_data
3、update.py
#channels包相关
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layerclass AllDataConsumersUpdate:'''功能:在http视图中,给房间组=chat_all_data 推送指定的消息'''def _make_channel_layer(self,send_data):''':param send_data: 在http视图中查询好的数据,要给房间组内所有的websocket对象发送数据'''channel_layer = get_channel_layer()#拿到房间组名group_name = 'chat_all_data'#给该房间组组内发送数据 注意是group_send方法async_to_sync(channel_layer.group_send)(group_name, #房间组名,给这个房间组发送数据{'type':'send_to_chrome', #处理这个房间组的消费者类必须有send_to_chrome方法'data':send_data #要发送给websocket对象的数据})'''send_to_chrome: 该房间组对应的消费者,必须存在这个函数,在这个函数中进行将数据发送给房间组所有的websocket对象send_data : 查询出来的数据'''#用户管理-搜索用户页面-实时更新数据,由前端自己去获取数据def search_user_data(self):send_data = {'type':'search_user_data','page_update':1}#给房间发送数据self._make_channel_layer(send_data=send_data)return True
4、routings.py
from django.urls import path
from . import consumers# 这个变量是存放websocket的路由
socket_urlpatterns = [path('socket/all/',consumers.AllDataConsumers.as_asgi()),]
四、修改settings.py同级的asgi.py文件
asgi.py
import osfrom django.core.asgi import get_asgi_application#新的模块
from channels.routing import ProtocolTypeRouter, URLRouter
# 导入websocket的路由模块
from apps.websocket import routings#项目名,settings.py所在的目录名
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '项目名.settings')application = ProtocolTypeRouter({# http路由走这里"http": get_asgi_application(),# chat应用下rountings模块下的路由变量socket_urlpatterns,就是存路由的列表"websocket": URLRouter(routings.socket_urlpatterns)
})
五、在视图函数中怎么发送websocket通知
from apps.websocket.update import websocket_update_obj #websocket推送数据的接口#在视图函数中直接调用需要的方法就可以实现推送了
websocket_update_obj.search_user_data()
将所有的推送方法都放到一个类中,可以很方便的进行管理,后期修改时,也可以实现统一的修改。
六、启动项目
python manage.py runserver 8005
看到 ASGI/Channels Version xxx 就说明启动成功,此时的django项目才支持websocket
七、测试
访问:EasySwoole-WebSocket在线测试工具
-
1、服务地址:http://127.0.0.1:8005/socket/all/
-
2、点击连接
-
3、发送数据:{"type":"search_user_data"}
-
4、点击发送
相关文章:

Django3框架-(3)-[使用websocket]:使用channels实现websocket功能;简化的配置和实际使用方式
概述: 对于Django使用channels实现websocket的功能,之前就写了几篇博文了。随着在项目的使用和实际维护来说,重新设置了相关处理方法。 一般来说,前后端都只维护一个全局的连接,通过携带数据来判断具体的操作&#x…...
java-工具类抛异常
不满足条件就会报错,这里的accessors ! null,就是等于空的时候(不满足)就会报错 accessors null; Assert.isTrue(ObjectUtil.isNotEmpty(accessors ! null), "数据为空");...

Navicat连接postgresql数据库 -->华为云服务器
Navicat连接postgresql数据库 -->华为云服务器 2.开放服务器端口:54323.Navicat连接postgresql数据库 2.开放服务器端口:5432 1-1.选择安全组 1-2. 添加规则 1-3.开放5432端口规则 1-4.查看规则 3.Navicat连接postgresql数据库...

Leetcode2086. 从房屋收集雨水需要的最少水桶数
Every day a Leetcode 题目来源:2086. 从房屋收集雨水需要的最少水桶数 解法1:贪心 我们可以对字符串 hamsters 从左到右进行一次遍历。 每当我们遍历到一个房屋时,我们可以有如下的选择: 如果房屋的两侧已经有水桶ÿ…...

Pandas教程(非常详细)(第一部分)
Pandas 库是一个免费、开源的第三方 Python 库,是 Python 数据分析必不可少的工具之一,它为 Python 数据分析提供了高性能,且易于使用的数据结构,即 Series 和 DataFrame。Pandas 自诞生后被应用于众多的领域,比如金融…...
typing.Union` 标注一多种变量类型
typing.Union 标注一多种变量类型 typing.Union 是Python typing 模块中用于标注一个变量可以是多种类型之一的类型提示。在Python 3.10版本及以后,推荐使用 | 运算符代替 Union。不过,在详细介绍 Union 的用法前,值得注意的是在大多数情况下…...

OSPF高级特性
OSPF高级特性(1) 一、OSPF不规则区域类型 产生原因:区域划分不合理,导致的问题 1、非骨干区域无法和骨干区域保持连通 2、骨干区域被分割 造成后果:非骨干区域没和骨干区域相连,导致ABR将不会帮忙转发区域间的路由信息。非骨干区…...
mysql中日期的加减 date_add()、date_sub() 函数
一、说明 DATE_ADD() :从日期增加指定的时间间隔,返回的是一个字符串 DATE_ADD(date,INTERVAL expr type) date 参数是合法的日期表达式。expr 参数是您希望添加的时间间隔。 type 参数可以是下列值 二、使用 now() //now函数为获取当前时间 sele…...

实在智能携手品牌商家,在活动会面中共谋发展
金秋十月,丰收的季节,也是商家们在双11大展拳脚的时刻。为迎战一年一度的双11大促,品牌商家在10月份卯足劲,制定一系列营销方案,争取为店铺带来更多流量和订单。 其中,舍得、同科医药、梅子熟了、宝洁、维…...

EXSi系统安装与使用
文章目录 EXSi系统安装与使用EXSi系统安装1.打开VMware Workstation软件2.安装系统3.配置虚拟机 使用EXSi登录web页面扩充存储创建虚拟机使用虚拟机 EXSi系统安装与使用 EXSi系统安装 1.打开VMware Workstation软件 创建虚拟机 2.安装系统 等待 回车 F11 回车 回车 设置密码…...

Spring MVC (Next-1)
1.Restful请求 restFul是符合rest架构风格的网络API接口,完全承认Http是用于标识资源。restFul URL是面向资源的,可以唯一标识和定位资源。 对于该URL标识的资源做何种操作是由Http方法决定的。 rest请求方法有4种,包括get,post,put,delete.分别对应获取…...

双目视觉检测 KX02-SY1000型测宽仪 有效修正和消除距离变化对测量的影响
双目视觉检测的基本原理 利用相机测量宽度时,由于单个相机在成像时存在“近大远小”的现象,并且单靠摄入的图像无法知道被测物的距离,所以由被测物的跳动导致的被测物到工业相机之间距离变化,使测量精度难以提高。 因此测宽仪需…...

C++ 面向对象 学习 优秀教程
油管看视频 沉浸式翻译插件,实现中文字幕! 文章目录 Object Oriented Programming (OOP) in C Course Object Oriented Programming (OOP) in C Course https://www.youtube.com/watch?vwN0x9eZLix4 博主:https://www.youtube.com/CodeBeau…...

Python笔记——pyChram连接linux子系统,使用linux下的Python进行编译
Python笔记——pyChram连接linux子系统,使用linux下的Python进行编译 Linux子系统安装与配置安装前准备安装Linux子系统安装Python3.8配置pyCharm 最近要跑的实验里,python有个机器学习的库windows环境下是没有的,在linux环境下有。虚拟机又不…...

【数据结构】数组和字符串(七):特殊矩阵的压缩存储:三元组表的转置、加法、乘法操作
文章目录 4.2.1 矩阵的数组表示4.2.2 特殊矩阵的压缩存储a. 对角矩阵的压缩存储b~c. 三角、对称矩阵的压缩存储d. 稀疏矩阵的压缩存储——三元组表4.2.3三元组表的转置、加法、乘法、操作转置加法乘法算法测试实验结果代码整合 4.2.1 矩阵的数组表示 【数据结构】数组和字符串…...

Spring底层原理(四)
Spring底层原理(四) 本章内容 模拟实现Spring中的几个常见BeanFactory后置处理器 常见的BeanFactory后置处理器 GenericApplicationContext context new GenericApplicationContext(); context.registerBean("config",Config.class); context.registerBean(Conf…...
Android 14 rook替代Postern进行中间人抓包
以下是关于使用Brook替代Postern进行中间人抓包的说明: 先来解释下,为什么用Postern而不用fd,fd属于代理抓包。Postern属于是模拟出来一张虚拟网卡抓包。性质不一样,所以害怕大哥问我。我就先放在这里 在Android 14及之前的版本中…...
[rancher] rancher部署和使用的一些思考
最近因为工作需要,学习调研rancher的使用 k8s作为主流微服务部署的基础,已经逐渐在工作中普及。但是k8s dashboard用于生产管理,还是有所欠缺:我们需要一个k8s之上的管理平台。经过调研,目前rancher已经迭代开发至v2.8…...

迅镭激光董事长颜章健荣膺“2023年如皋市科技强企人物”!
10月28日,2023如皋科技人才洽谈会开幕式在如皋隆重举行。江苏省科学技术厅副厅长、党组成员蒋洪,江苏省商务厅副厅长、党组成员孙津,中共南通市委副书记、政法委书记沈雷,中共如皋市市委书记何益军,中共如皋市委副书记…...

专业医学病例翻译公司推荐
我们知道,医学病例翻译在涉外看病的患者中具有广泛的应用,它可以帮助医生快速了解患者的病情,为治疗和药物处方提供关键信息。因此,对于出国看病的患者,医学病例翻译便成了不可或缺的重要工具。 翻译医学病例不仅要求译…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...