Django框架:使用channels实现websocket,配置和项目实际使用
一、基本配置
依赖包:
Django==3.2 django-cors-headers==3.5.0 redis==4.6.0 #操作redis数据库的 channels==3.0.0 #websocket channels-redis==4.1.0 #通道层需要,依赖redis包
项目目录结构:
study_websocket
--study_websocket
--__init__.py
--settings.py
--asgi.py
--wsgi.py
--urls.py
--chat
--routings.py
--consumers.py
--update.py
--urls.py
--views.py
1.1、settings.py配置
1、注册跨域、channels、chat应用
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','corsheaders', #前后端跨域'chat.apps.WebsocketConfig',#专门用于写websocket的方法'channels', #django通过其实现websocket
]
2、跨域配置
##### 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' #请求头允许自定义的字符串
)
3、channels需要的配置
WSGI_APPLICATION = 'study_websocket.wsgi.application'
#channels使用需要添加ASGI_APPLICATION
ASGI_APPLICATION = 'study_websocket.asgi.application'
#通道层:开发阶段使用内存
CHANNEL_LAYERS = {"default": {"BACKEND": "channels.layers.InMemoryChannelLayer"}
}
1.2、在chat应用新增routings.py 和 consumers.py
1、consumers.py设置一个简单消费者
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
from asgiref.sync import async_to_sync
import timeclass ChatView(WebsocketConsumer):def websocket_connect(self, message):#客户端与服务端进行握手时,会触发这个方法#服务端允许客户端进行连接,就是握手成功self.accept()def websocket_receive(self, message):#接收到客户端发送的数据recv = message.get('text')print('接收到的数据,',recv)if recv == 'close':#服务的主动断开连接print('服务器断开连接')self.close()else:#客户端向服务端发送数据self.send(f'我收到了,{time.strftime("%Y-%m-%d %H:%M:%S")}')def websocket_disconnect(self, message):#客户端端口连接时,会触发该方法,断开连接print('客户端断开连接')raise StopConsumer()
2、配置routings.py
from django.urls import path
from . import consumers#这个变量是存放websocket的路由
socket_urlpatterns = [path('chat/socket/',consumers.ChatView.as_asgi()),
]
1.3、修改跟settings.py同级目录下的asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter,URLRouter
#导入chat应用中的路由模块
from chat import routingsos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'study_websocket.settings')
application = ProtocolTypeRouter({#http路由走这里"http":get_asgi_application(),#chat应用下rountings模块下的路由变量socket_urlpatterns"websocket":URLRouter(routings.socket_urlpatterns)
})
1.4、启动项目
启动命令:python manage.py runserver 8888
启动提示:如下就是配置成功了

在线测试websocket的网站:
EasySwoole-WebSocket在线测试工具EasySwoole在线WebSocket测试工具
http://www.easyswoole.com/wstool.html
服务地址:ws://127.0.0.1:8888/chat/socket/ 点击开启连接
连接成功后,就可以向服务端发送数据了。
二、房间组使用(聊天室:待更新)
三、房间组使用(非聊天室)
概述:
data = {'type':'xxx'}
1、前端只想维护一个全局的websocket对象,通过发送的数据中type的不同获取到不同的数据。
2、在后端给前端主动推送数据时,也是通过这个type来确定要重新渲染的数据。
构建想法:
1、设置一个处理全局websocket的消费者类
2、设置一个全局websocket都进入的房间组
3、在chat应用下新建一个update.py: websocket返回数据 和主动推送数据都放到这个模块中
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 websocket.update 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']token = Nonefor key,value in headers:if key == b'token':token = value.decode('utf-8')if token:print(token)else: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':'传递的数据有问题'},ensure_ascii=False))self.disconnect(400)return#个人信息:所有的老人信息if the_type == 'all_patient_page_data':send_data = base_send(text_data_json)self.send(json.dumps(send_data,ensure_ascii=False))#来访登记:进行中的来访登记if the_type == 'all_active_visit_data':send_data = base_send(text_data_json)self.send(json.dumps(send_data,ensure_ascii=False))#自定义的处理房间组内的数据def send_to_chrome(self, event):try:data = event.get('data')#接收房间组广播数据,将数据发送给websocketself.send(json.dumps(data,ensure_ascii=False))except Exception as e:error_logger.exception(str(e),'给全局的websocket推送消息失败')
update.py
import json
from datetime import datetime,timedelta
from django.db.models import Q#channels包相关
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layerdef base_send(data:dict):'''功能:发起websocket请求时,给当前websocket返回查询到的数据'''the_type = data.get('type')id = data.get('id')send_data = {'type':the_type,}#个人管理-首次进入时,没有点击搜索时,这个需要实时获取if the_type == 'all_patient_page_data':send_data['data'] = '数据库查询到的数据:个人管理'return send_data#来访登记:进行中的来访记录if the_type == 'all_active_visit_data':send_data['data'] = '数据库查询到的数据:来访记录'return send_data#class AllDataConsumersUpdate:'''功能:在http视图中,给房间组=chat_all_data 推送指定的消息在视图函数中,某些数据更新了,需要通知所有的websocket对象'''def _make_channel_layer(self,send_data):''':param send_data: 在http视图中查询好的数据,要给房间组内所有的websocket对象发送数据'''channel_layer = get_channel_layer()#拿到房间组名group_name = 'chat_all_data'#给该房间组组内发送数据async_to_sync(channel_layer.group_send)(group_name,{'type':'send_to_chrome', #消费者中处理的函数'data':send_data})#个人信息:def all_patient_page_data(self):try:send_data = {'type':'all_patient_page_data','data':'更新数据了,个人信息'}#把更新的数据发送到房间组内self._make_channel_layer(send_data=send_data) except Exception as e:pass#来访登记:def all_active_visit_data(self):try:send_data = {'type':'all_patient_page_data','data':'更新数据了,来访登记'}#把更新的数据发送到房间组内self._make_channel_layer(send_data=send_data) except Exception as e:error_logger.exception(str(e))
rountings.py
from django.urls import path
from . import consumers#这个变量是存放websocket的路由
socket_urlpatterns = [path('chat/socket/',consumers.ChatView.as_asgi()),path('socket/all/',consumers.AllDataConsumers.as_asgi()),
]
两个视图函数
from chat.update import AllDataConsumersUpdate #2023-07-25:模拟来访记录变化 update = AllDataConsumersUpdate() update.all_active_visit_data()
from chat.update import AllDataConsumersUpdate
#2023-07-25:模拟个人信息编变化 update = AllDataConsumersUpdate() update.all_patient_page_data()
1、先使用测试网站连接上:
EasySwoole-WebSocket在线测试工具
2、再访问写的两个视图函数,看websocket是否返回数据
业务逻辑:
1、创建连接时,把websocket对象放到同一个房间组内
2、当是websocket对象主动给后端发送数据时,后端只对这个websocket对象返回数据
3、当在视图中调用主动推送的方法,
a.把数据发送到房间组内
b.通过设置好的处理方法send_to_chrome 来实现从房间组内拿到数据,发送给websocket对象
相关文章:
Django框架:使用channels实现websocket,配置和项目实际使用
一、基本配置 依赖包: Django3.2 django-cors-headers3.5.0 redis4.6.0 #操作redis数据库的 channels3.0.0 #websocket channels-redis4.1.0 #通道层需要,依赖redis包项目目录结构: study_websocket --study_websocket --__init__.py --s…...
基于RK3588+FPGA+AI算法定制的智慧交通与智能安防解决方案
随着物联网、大数据、人工智能等技术的快速发展,边缘计算已成为当前信息技术领域的一个热门话题。在物联网领域,边缘计算被广泛应用于智慧交通、智能安防、工业等多个领域。因此,基于边缘计算技术的工业主板设计方案也受到越来越多人的关注。…...
AI面试官:LINQ和Lambda表达式(一)
AI面试官:LINQ和Lambda表达式(一) 当面试官面对C#中关于LINQ和Lambda表达式的面试题时,通常会涉及这两个主题的基本概念、用法、实际应用以及与其他相关技术的对比等。以下是一些可能的面试题目,附带简要解答和相关案…...
FPGA学习——FPGA利用状态机实现电子锁模拟
文章目录 一、本次实验简介二、源码及分析三、总结 一、本次实验简介 本次是实验是为了利用状态机模拟电子锁,相关要求如下: 顺序输入4位密码,密码为1234,用按键来键入密码用led灯指示键入第几位密码,(博…...
Bert经典变体学习
ALBert ALBERT就是为了解决模型参数量大以及训练时间过长的问题。ALBERT最小的参数只有十几M, 效果要比BERT低1-2个点,最大的xxlarge也就200多M。可以看到在模型参数量上减少的还是非常明显的,但是在速度上似乎没有那么明显。最大的问题就是这种方式其实…...
uniapp checkbox radio 样式修改
文章目录 通过查看代码,发现 before部分是设置样式的主要属性 我们要设置的话,就要设置checkbox::before的属性。 其中的content表示内容,比如内部的对勾 那么我们设置的时候,比如设置disabletrue的时候或者checkedtrue的时候&…...
电脑重启后VScode快捷方式失效,找不到Code.exe
问题描述 下班回家关了部分程序就直接关机了,回家后重启电脑发现vscode的快捷方式就失效了,提示Code.exe已被移动或删除。 解决方法 查看你的vscode安装目录,Microsoft VS Code目录下大概率会存在一个名为_的文件夹,然后会发现…...
C语言实现扫雷游戏
test.c源文件 - 扫雷游戏测试 game.h头文件 - 扫雷游戏函数的声明 game.c源文件 - 扫雷游戏函数的实现 1.布置雷 -- 存放雷的雷盘 9*9 数组设计成11*11 上下左右方各多一行,保证周围8的范围 雷 - 1 不是雷 - 0 2.排查雷 主题测试源文件代码 &…...
蓝图节点编辑器
打印字符串 第02章 蓝图结构 03 -注释和重新路由_哔哩哔哩_bilibili 第02章 蓝图结构 04 - 变量_哔哩哔哩_bilibili 第03章 蓝图简易门 01 - 箱子碰撞_哔哩哔哩_bilibili 第03章 蓝图简易门 02 - 静态Mesh和箭头_哔哩哔哩_bilibili 第03章 蓝图简易门 03 - 设置相对旋转节点_哔…...
MySql 知识大汇总
数据库索引 数据库索引是一种数据结构,用于提高数据库查询的速度和效率。索引可以看作是表中一列或多列的值的快速查找方式,类似于书籍的目录。通过创建索引,可以减少数据库的扫描量,加快数据的检索速度。 常见的索引类型 常见…...
深入浅出Pytorch函数——torch.sum
分类目录:《深入浅出Pytorch函数》总目录 相关文章: 深入浅出Pytorch函数——torch.Tensor 函数torch.sum有两种形式: torch.sum(input, *, dtypeNone):返回输入张量input所有元素的和。torch.sum(input, dim, keepdimFalse, *,…...
Git克隆文件不显示绿色勾、红色感叹号等图标
1、问题 Git和TorToiseGit安装后,Git克隆的文件不会显示绿色勾、红色感叹号等图标。 2、检查注册表 2.1、打开注册表 (1)WinR打开运行窗口,输入regedit,点击确定,打开注册表编辑器。 2.2、找如下路径 (1)找到路径 计算机\HKEY_…...
SOC FPGA之HPS模型设计(一)
目录 一、建立HPS硬件系统模型 1.1 GHRD 1.2 从0开始搭建HPS 1.2.1 FPGA Interfaces 1.2.1.1 General 1.2.1.2 AXI Bridge 1.2.1.3 FPGA-to-HPS SDRAM Interface 1.2.1.4 DMA Peripheral Request 1.2.1.5 Interrupts 1.2.1.6 EMAC ptp interface 1.2.2 Peripheral P…...
解决openstack重启swift服务后报错
swift重启报错 问题描述解决办法 问题描述 swift服务正常状态如下 [rootcontroller ~]# swift statAccount: AUTH_8bde12ff804e42498661b7454994c446Containers: 0Objects: 0Bytes: 0X-Put-Timestamp: 1690507907.67931X-Timestamp: 1690507907.67931X-Trans-Id: tx56d22fa13…...
[Linux]进程控制详解!!(创建、终止、等待、替换)
hello,大家好,这里是bang___bang_,在上两篇中我们讲解了进程的概念、状态和进程地址空间,本篇讲解进程的控制!!包含内容有进程创建、进程等待、进程替换、进程终止!! 附上前2篇文章…...
全面适配 | 走近openGauss数据库+鲲鹏欧拉操作系统
引入 全面适配 | openEuler操作系统 openGauss数据库 开篇 1、openEuler欧拉操作系统 百度百科:openEuler是覆盖全场景的创新平台,在引领内核创新,夯实云化基座的基础上,面向计算架构互联总线、存储介质发展新趋势,…...
2023Robocom CAIP省赛 第四题 相对论大师
原题链接: PTA | 程序设计类实验辅助教学平台 题面: 在某个直播间里,观众常常会发送类似这样的弹幕: 鱼越大,鱼刺越大;鱼刺越大,肉越少;肉越少,鱼越小;所以鱼…...
【TypeScript】TS入门级基础学习(一)
【TypeScript】TS入门级基础学习(一) 一、前言 TypeScript 是一种用于应用程序规模的 JavaScript 语言。 TypeScript 向 JavaScript 添加了可选类型,支持用于任何浏览器、任何主机、任何操作系统的大规模 JavaScript 应用程序的工具。 Type…...
jenkins执行jmeter时,报Begin size 1 is not equal to fixed size 5
jenkins执行jmeter脚本的时候一直提示如下错误: Tidying up ... Fri Jul 28 17:03:53 CST 2023 (1690535033178) Error generating the report: org.apache.jmeter.report.dashboard.GenerationException: Error while processing samples: Consumer failed wi…...
在 “小小容器” WasmEdge 里运行小小羊驼 llama 2
昨天,特斯拉前 AI 总监、OpenAI 联合创始人 Andrej Karpathy 开源了 llama2.c 。 只用 500 行纯 C 语言就能训练和推理 llama 2 模型的框架,没有任何繁杂的 python 依赖。这个项目一推出就受到大家的追捧,24 小时内 GitHub 收获 4000 颗星&am…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
