LuckySheet协同编辑后端示例(Django+Channel,Websocket通信)

其他的配置不赘述了,直接网上搜一下django使用channel的配置方法

我初步研究通道先用的内存
在setting文件中
 

CHANNEL_LAYERS = {"default": {"BACKEND": "channels.layers.InMemoryChannelLayer",},
}

这里我重点说一下luckysheet源码的部分

首先是websocket,这部分代码在源码的server.js中,通过研究源码,才解决了问题

pako解压的问题尝试了很多次都没不太对,于是直接把pako部分的源码给注释掉了,直接传过去的就是json字符串

} else {// let msg = pako.gzip(encodeURIComponent(JSON.stringify(d)), {to: "string"});let msg = JSON.stringify(d);//console.info(msg);if (_this.websocket != null) {_this.websocket.send(msg);}}

后端的消费者类的主要代码如下

from channels.generic.websocket import AsyncJsonWebsocketConsumer
from urllib.parse import parse_qs
import jsonclass TableConsumer(AsyncJsonWebsocketConsumer):table = NonegridKey = Noneasync def connect(self):query = self.scope['query_string'].decode('utf-8')t = parse_qs(query)['t'][0]self.gridKey = parse_qs(query)['g'][0]await self.channel_layer.group_add(f'table_{self.gridKey}', self.channel_name)await self.accept()print('建立连接')async def disconnect(self, close_code):print('断开连接')await self.channel_layer.group_discard(f'table_{self.gridKey}', self.channel_name)async def receive(self, text_data=None, bytes_data=None):# 使用json.loads方法将JSON字符串解析为Python的字典对象if text_data !='rub':parsed_data = json.loads(text_data)print(parsed_data)# 这里构造要广播的数据broadcast_data = dict()broadcast_data['type'] = 3broadcast_data['data'] = text_databroadcast_data['username'] = 'test'broadcast_event = {"type": "broadcast_message","message": broadcast_data}# 向对应的组发送广播事件,触发broadcast_message方法来实际发送给组内成员await self.channel_layer.group_send(f'table_{self.gridKey}', broadcast_event)async def broadcast_message(self, event):message = event["message"]await self.send_json(message)

之前对websocket和channel不太了解,看了前端代码后把type和message给改了,后来多次尝试发现这个千万别改,他会在send的时候卡住而且不报任何错误(因为协程),如果是广播的话只需要修改broadcast_data的内容就行,通过解读前端的代码,在后端构建返回的json,成果把type=3的内容实现了,也就是鼠标移动的部分

else if(type == 3){ //多人操作不同选区("t": "mv")(用不同颜色显示其他人所操作的选区)let id = data.id;let username = data.username;let item = JSON.parse(data.data);let type = item.t,index = item.i,value = item.v;

剩余的部分我就先不写了,具体操作应该是根据前端过来的json内容来自行判断返回的type,然后进行消息的分发!!!!

重点:读源码读源码读源码!!!!!

又写了两种type,批量的没写到type=4的情况,因为他前端写的感觉有问题还造成了后端的麻烦,于是后端写成多个type=2了,增加了一点点服务器压力

from channels.generic.websocket import AsyncJsonWebsocketConsumer
from urllib.parse import parse_qs
import jsonfrom pyasn1_modules.rfc5639 import brainpoolP160r1class TableConsumer(AsyncJsonWebsocketConsumer):table = NonegridKey = Noneasync def connect(self):query = self.scope['query_string'].decode('utf-8')t = parse_qs(query)['t'][0]self.gridKey = parse_qs(query)['g'][0]await self.channel_layer.group_add(f'table_{self.gridKey}', self.channel_name)await self.accept()print('建立连接')async def disconnect(self, close_code):print('断开连接')await self.channel_layer.group_discard(f'table_{self.gridKey}', self.channel_name)async def receive(self, text_data=None, bytes_data=None):# 使用json.loads方法将JSON字符串解析为Python的字典对象if text_data !='rub':parsed_data = json.loads(text_data)print(parsed_data)if parsed_data['t'] == 'mv':# 这里构造要广播的事件数据,假设要原封不动广播接收到的数据,将其放入'message'字段broadcast_data = dict()broadcast_data['type'] = 3broadcast_data['data'] = text_databroadcast_data['username'] = 'test'broadcast_event = {"type": "broadcast_message","message": broadcast_data}# 向对应的组发送广播事件,触发broadcast_message方法来实际发送给组内成员await self.channel_layer.group_send(f'table_{self.gridKey}', broadcast_event)if parsed_data['t'] == 'v':# 这里构造要广播的事件数据,假设要原封不动广播接收到的数据,将其放入'message'字段broadcast_data = dict()broadcast_data['type'] = 2broadcast_data['data'] = text_databroadcast_data['username'] = 'test'broadcast_event = {"type": "broadcast_message","message": broadcast_data}# 向对应的组发送广播事件,触发broadcast_message方法来实际发送给组内成员await self.channel_layer.group_send(f'table_{self.gridKey}', broadcast_event)if parsed_data['t'] == 'rv':row = parsed_data['range']['row']column = parsed_data['range']['column']for j in range(column[0], column[1]+1):numj = j-column[0]for i in range(row[0], row[1] + 1):numi = i-row[0]try:broadcast_data = dict()broadcast_data['type'] = 2# data = list()broadcast_data['username'] = 'test'data = dict()data['t'] = 'v'data['i'] = 0data['v'] = parsed_data['v'][numi][numj]data['r'] = idata['c'] = jbroadcast_data['data'] = json.dumps(data)broadcast_event = {"type": "broadcast_message","message": broadcast_data}await self.channel_layer.group_send(f'table_{self.gridKey}', broadcast_event)except Exception as e:print(e)async def broadcast_message(self, event):message = event["message"]await self.send_json(message)

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

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

相关文章

delphi fmx android 离线人脸识别

搜遍全网都没有找到delphi android 能用的 离线人脸识别,无需注册什么开发者 有这方面需求的可以用fsdk 这边用的luxand.FSDK8.0 android下的注册号要自己找下 1,用老猫的工具将android 下的sdk,FSDK.java 编译成FSDK.jar 老猫的工具 2,用上面的工具将FSDK.jar 生成de…

RabbitMQ教程:工作队列(Work Queues)(二)

RabbitMQ教程:工作队列(Work Queues)(二) 一、引言 在快节奏的软件开发世界中,我们经常面临需要异步处理任务的场景,比如在Web应用中处理耗时的图片处理或数据分析任务。这些任务如果直接在用…

乐维网管平台(七):网络稳定与高效的“安全锦囊”

试想一下,你给电脑升级了一个软件,升级完成后发现有BUG,经常无故卡死,这时候想回退或重新安装旧版本…相对地,一家企业的网络管理员,在对公司的核心交换机进行复杂的配置调整时,一个小小的疏忽&…

时代变迁对传统机器人等方向课程的巨大撕裂

2020年之后,全面转型新质课程规划,传统课程规划全部转为经验。 农耕-代表性生产关系-封建分配制度主要生产力-人力工业-代表性生产关系-资本分配制度工业分为机械时代,电气时代,信息时代;主要生产力-人力转为人脑&…

Spring6 AOP 面向切面编程

1. 概念 面向切面编程:一种编程思想。proxy动态代理(实现了这种思想):在原方法执行时,给原方法的前面或着后面增加其他的方法。增加的方法并不会写在原方法中 原方法就是目标方法,增加的方法就是代理方法 …

计算机组成与原理(2) basic of computer architecture

Instruction Set Architecture (ISA) 和 Hardware System Architecture (HSA) 是计算机体系结构中两个重要的层次,它们各自的职责和作用如下: Instruction Set Architecture (ISA) 定义 ISA是指令集体系结构,是硬件和软件之间的接口。它定义…

window的wsl(Ubuntu)安装kafka步骤

环境:Win11 WSL(Linux子系统Ubuntu) apache-zookeeper-3.9.3-bin kafka_2.12-3.8.1 思路:apache上分别下载zookeeper和kafka,在wsl环境安装。在kafka上创建消息的topic,发送消息,接受消息,验证是否安…

数据结构树和二叉树知识点和递归序列

二叉树知识点 一.树的概念1.1关于树的名词解释 二.二叉树的概念1. 二叉树性质: 三.满二叉树与完全二叉树递归前序遍历递归中序遍历递归后续遍历 一.树的概念 树是一种非线性数据结构,它是由n个或大于n个的结点来组成具有层次关系的一个集合(…

速通前端篇 —— CSS

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏:速通前端 目录 CSS的介绍 基本语法规范 CSS选择器 标签选择器 class选择器 id选择器 复合选择器 通配符选择器 CSS常见样式 颜…

使用 Elastic 3 步实现基于 OTel 的原生 K8s 和应用可观测性

作者:来自 Elastic Bahubali Shetti Elastic 的 OpenTelemetry 发行版现已支持 OTel Operator,可使用 EDOT SDK 自动检测应用程序,并管理 EDOT OTel Collector 的部署和生命周期以实现 Kubernetes 可观察性。了解如何通过 3 个简单步骤进行配…

stack、queue、priority_queue、deque的使用和模拟实现

目录 1.容器适配器 2.stack stack的常用接口及使用示例 stack的模拟实现 3.queue queue的常用接口及使用示例 queue的模拟实现 4.priority_queue priority_queue的常用接口及使用示例 priority_queue的模拟实现 5.deque 认识deque deque底层的数据结构 deque和ve…

Linux的cuDNN(cudnn)安装教程(CUDA(cuda\cuda toolkit))

CUDA(cuda\cuda toolkit)安装教程 https://blog.csdn.net/huiyayaya/article/details/143863835?spm1001.2014.3001.5502官网下载cudnn https://developer.nvidia.com/rdp/cudnn-archive这个下载到自己的电脑 下载到本地就好 复制到服务器 切换到cudnn文件所在目…

Kafka中ACKS LSO LEO LW HW AR ISR OSR解析

名称解释 ACKS(Acknowledgments)确认、回执 LW(Low watermark)低水位、LSO(Log start offset)起始偏移量 HW(High watermark)高水位 LEO(Log end offset)…

C++设计模式行为模式———迭代器模式

文章目录 一、引言二、迭代器模式三、总结 一、引言 迭代器模式是一种行为设计模式, 让你能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。C标准库中内置了很多容器并提供了合适的迭代器,尽管我们不…

智能体Agent调研

单个智能体建模与优化现状 人类长期以来追求类似于或超越人类水平的人工智能 (AI),而 基于AI的代理(Agent)被认为是一个有前途的研究方向。传统计算机领域的Agent有多种,如自动化脚本、网络爬虫、推荐系统、软件机器人能够独立自…

SAP PI/PO Proxy2JDBC SQL_QUERY动态接口示例

目录 背景: 完整demo步骤: IR: ID: SPROXY: 测试代码: 注意点: 背景: 中途临时帮客户项目做其他功能,项目上有部分开发项需要通过PO去第三方数据库取数,项目上的开发对PO不太熟&#xf…

【汇编语言】数据处理的两个基本问题(三) —— 汇编语言的艺术:从div,dd,dup到结构化数据的访问

文章目录 前言1. div指令1.1 使用div时的注意事项1.2 使用格式1.3 多种内存单元表示方法进行举例1.4 问题一1.5 问题一的分析与求解1.5.1 分析1.5.2 程序实现 1.6 问题二1.7 问题二的分析与求解1.7.1 分析1.7.2 程序实现 2. 伪指令 dd2.1 什么是dd?2.2 问题三2.3 问…

模型的评估指标——IoU、混淆矩阵、Precision、Recall、P-R曲线、F1-score、mAP、AP、AUC-ROC

文章目录 预测框的预测指标——IoU(交并比)分类预测指标混淆矩阵(Confusion Matrix,TP、FP、FN、TN)Precision(精度)Recall(召回率)P-R曲线F1-scoreTPR、TNR、FPR、FNRROC曲线下面积…

轻量云服务器:入门级云计算的最佳选择

在云计算领域,轻量云服务器逐渐成为小型企业、个人开发者和初创公司关注的热点。它凭借高性价比、简单易用和稳定性能,正在改变传统的服务器部署方式。本文将详细解析轻量云服务器的定义、优势、适用场景及如何选择最佳方案,帮助您全面了解这…

【初阶数据结构篇】归并排序、计数排序

文章目录 须知 💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力! 👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗&#xff1…