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…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...