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测试工具icon-default.png?t=N6B9http://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对象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/12522.shtml

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

相关文章

3dsmax制作一个机器人

文章目录 建模身子:眼睛:头饰:肩膀手臂腿调整细节 渲染导出objMarmoset Toolbag 3.08渲染给眼睛添加材质,设置为自发光添加背景灯光 建模 身子: 眼睛: 头饰: 肩膀 手臂 腿 调整细节 渲染 导出…

Android性能优化之游戏引擎初始化ANR

近期,着手对bugly上的anr 处理,记录下优化的方向。 借用网上的一张图: 这里的anr 问题是属于主线程的call 耗时操作。需要使用trace 来获取发生anr前一些列的耗时方法调用时间,再次梳理业务,才可能解决。 问题1 ja…

【Linux进程】进程控制(下) {进程程序替换:程序替换的工作原理,程序替换函数exec*,简单的命令行解释器}

四、进程程序替换 之前用fork创建子进程后,父子进程执行同一个程序的不同代码段。 如何使子进程执行另一个不同的程序呢?子进程需要进行程序替换! 程序替换,就是通过特定的接口,将磁盘上一个全新的程序(包…

❤ Win7 电脑的使用

❤ Win7 电脑的使用 日常使用 1、 电脑显示文件的后缀名 开发使用 1、win7启动Vue项目 新版本的node.js已经不支持win7操作系统,其最多只能用node.js的v13.14.0。所以安装vue/cli时不能安装最新版,得装指定版本 下载安装node.js 因为Win7系统最多…

Python Web开发技巧VII

目录 装饰器inject_serializer 装饰器atomic rebase git 清理add的数据 查看git的当前工作目录 makemigrations文件名称 action(detailTrue, methods["GET"]) 如何只取序列化器的一个字段进行返回 Response和JsonResponse有什么区别 序列化器填表和单字段如…

数学建模-蒙特卡洛模拟

%% 蒙特卡罗用于模拟三门问题 clear;clc %% (1)预备知识 % randi([a,b],m,n)函数可在指定区间[a,b]内随机取出大小为m*n的整数矩阵 randi([1,5],5,8) %在区间[1,5]内随机取出大小为5*8的整数矩阵 % 2 5 4 5 3 1 4 2 %…

(无人机方向)ros小白之键盘控制无人机(终端方式)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一:配置pycharm的ros开发环境二:核心代码讲解三 效果演示XTDrone 四 完整代码 前言 ubuntu 18.04 pycharm ros melodic 做一个在终端中…

微信小程序——同一控件的点击与长按事件共存的解决方案

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…

植物一区HR | 植物生理组+转录组:揭示豆科植物响应干旱胁迫机制

PlantArray 植物高通量生理学表型监测系统 是一套以植物生理学为基础的高精度,高通量,自动化表型监测系统,集合实验设置、数据分析、决策工具于一身,能够高通量实时动态监测并进行全天候生理及环境参数采集,是进行植物…

网络设备中的配置文件管理

建立强大网络的第一步是为灾难和网络中断做好准备,许多企业在中断期间遭受损失,因为他们缺乏备份计划并且配置管理不达标,使用配置文件管理工具进行适当的配置文件管理不仅有助于处理网络中断,还有助于优化网络性能。 使用配置文…

海尔设计借助亚马逊云科技生成式AI,实现端到端的云上工业设计解决方案

海尔创新设计中心(以下简称海尔设计)成立于1994年,目前拥有400多名设计师,为海尔智家旗下七大品牌全球的所有产品提供设计创新和模式探索。亚马逊云科技为海尔设计提供了四个完整的云上解决方案,全面替代自有机房&…

Vue3 word如何转成pdf代码实现

🙂博主:锅盖哒 🙂文章核心:word如何转换pdf 目录 1.前端部分 2.后端部分 在Vue 3中,前端无法直接将Word文档转换为PDF,因为Word文档的解析和PDF的生成通常需要在后端进行。但是,你可以通过Vu…

HCIA 第二课总结

配置网络设备的明文密钥实验组网 实验拓扑 将一个路由器使用配置口进行连接 sys #进入系统视图模式 sysname RTA #给设备命名 user-interface console 0 #进入用户接口配置界面 authentication-mode password #配置认证模式为密钥认证 set authentication password ciphe…

百题千解计划【CSDN每日一练】订班服(附解析+多种实现方法:Python、Java、C、C++、C#、Go、JavaScript)

如果决意去做一件事了,就不要再问自己和别人值不值得,心甘情愿才能理所当然,理所当然才会义无反顾。 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌟[2] 2022年度博客之星人工智能领域TOP4🌟 🏅[3] 阿里云社区特邀专…

LeetCode刷题笔记-287题寻找重复数

LeetCode 287 寻找重复数 难度:中等 题目: 给定一个包含 n 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。 假设 nums 只有 一个重复的整数 ,返回…

软件外包开发测试管理工具

测试是软件工程中非常重要的一个环节,在上线前必须需要经过严格的测试才能确保上线后软件系统长时间运行。有大量的软件开发和测试管理工具,每一个工具都有自己的特点,今天和大家分享一些常见的工具,希望对大家有所帮助。北京木奇…

【Spring Boot丨序列化、反序列化】

序列化、反序列化 概述Jackson 序列化和反序列化简介自定义序列化器注册外部序列化程序: 指定类的 Json 序列化、反序列化 主页传送门:📀 传送 概述 序列化是将对象转换为字节序列的过程,而反序列化则是将字节序列恢复为对象的过…

监听镜像版本变化触发 GitOps工作流

文章目录 前言工作流总览安装和配置 ArgoCD Image Updater创建 Image Pull Secret(可选)创建 Helm Chart 仓库创建 ArgoCD Application删除旧应用(可选)配置仓库访问权限创建 ArgoCD 应用 体验 GitOps 工作流总结 前言 在【GitOps…

基于Citespace、vosviewer、R语言的文献计量学可视化分析技术及全流程文献可视化SCI论文高效写作方法

文献计量学是指用数学和统计学的方法,定量地分析一切知识载体的交叉科学。它是集数学、统计学、文献学为一体,注重量化的综合性知识体系。特别是,信息可视化技术手段和方法的运用,可直观的展示主题的研究发展历程、研究现状、研究…

【小波尺度谱】从分段离散小波变换计算小波尺度谱研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…