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.xdnf.cn/news/19032.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

数字化点亮库布其沙漠的绿色梦想

Bentley 应用程序助力提升设计和施工效率,提前六周交付设计成果 清洁能源为沙漠带来新活力 库布其光伏治沙项目(以下简称“该项目”)位于内蒙古鄂尔多斯市库布其沙漠,占地约 10 万亩,是中国单体规模最大的光伏治沙项目…

基于单片机的风能太阳能供电的路灯智能控制系统设计(论文+源码)

1系统总体设计 本课题为风能太阳能供电的路灯智能控制系统设计,系统的主要功能设计如下: (1) 供电模块:采用太阳能板以及风机模拟风扇充电,经过充电电路给锂电池进行充电。再由锂电池给照明模块以及整个项…

Linux Centos7 Rocky网卡配置

目录 1.Vmare 虚拟机配置 (1)打开虚拟机输入ip a,查看ip网段,若为192.168.81.135 (2)在Vmare上的虚拟网络配置器配置 (3)确保电脑有VMnet1 VMnet8 2.Linux虚拟机Centos配置 &#…

MySQL索引原理之查询优化

MySQL索引原理之查询优化 1、慢查询定位 开启慢查询日志 查看 MySQL 数据库是否开启了慢查询日志和慢查询日志文件的存储位置的命令如下: SHOW VARIABLES LIKE %slow_query_log%通过如下命令开启慢查询日志: SET global slow_query_log 1; SET global …

ArchGuard 架构分析器发布:多语言、跨项目架构数据生成,助力 AI 时代知识挖掘...

TL;DR:https://github.com/archguard/archguard 过去的几个月里,我们一直在探索用 AI 辅助跨项目、跨大量微服务的系统的开发。其中一个重要的话题就是,从现有的软件架构去生成知识,文档是落后、多版本的, 只有代码才保…

NLP论文速读(多伦多大学)|利用人类偏好校准来调整机器翻译的元指标

论文速读|MetaMetrics-MT: Tuning Meta-Metrics for Machine Translation via Human Preference Calibration 论文信息: 简介: 本文的背景是机器翻译(MT)任务的评估。在机器翻译领域,由于不同场景和语言对的需求差异&a…

工程车识别算法平台LiteAIServer算法定制工程车类型检测算法:建筑工地安全管理的得力助手

随着科技的飞速发展,智能化技术正在逐步改变我们的生活方式,特别是在交通管理和安全管理领域。其中,算法定制LiteAIServer工程车类型检测算法以其高效、准确和实时的特性,成为了建筑工地管理、矿山开采以及物流运输等多个领域的重…

机器学习2

三、特征工程 接机器学习1 4、特征降维 4.2、主成分分析PCA 从原始特征空间中找到一个新的坐标系统,使得数据在新坐标轴上的投影能够最大程度地保留数据的方差,同时减少数据的维度。 保留信息/丢失信息信息保留的比例 from sklearn.decomposition imp…

【Linux之权限】提升篇

前言 在前两篇文章里,我们已经学习了Linux中权限的理论、实践和重点,接下来我们将进一步提升对Linux权限的全面认知。虽是拓展,其实还是重点。 本文内容并不多,那我们就开始吧。 目录的权限该如何理解呢? 如果我想进…

亮数据结合AI大模型,实现数据自由

目录 一、获取网络数据的挑战1、反爬虫机制的威胁2、IP封锁与访问频率控制3、数据隐私与法律合规 二、亮数据动态代理:数据采集的最佳拍档1、高质量IP资源2、智能调度与自动切换3、合规与隐私保护4、多场景应用支持 三、使用亮数据代理 IP进行网络数据抓取1、引入 r…

elasticsearch是如何实现master选举的?

大家好,我是锋哥。今天分享关于【elasticsearch是如何实现master选举的?】面试题。希望对大家有帮助; elasticsearch是如何实现master选举的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Elasticsearch 中&…

EtherNet/IP转Profinet网关连接发那科机器人配置实例解析

本案例主要展示了如何通过Ethernet/IP转Profinet网关实现西门子1200PLC与发那科搬运机器人的连接。所需的设备有西门子1200PLC、开疆智能Ethernet/IP转Profinet网关以及Fanuc机器人。 具体配置步骤:打开西门子博图配置软件,添加PLC。这是配置的第一步&am…

Uniapp运行环境判断和解决跨端兼容性详解

Uniapp运行环境判断和解决跨端兼容性 开发环境和生产环境 uniapp可通过process.env.NODE_ENV判断当前环境是开发环境还是生产环境,一般用于链接测试服务器或者生产服务器的动态切换。在HX中,点击运行编译出来的代码是开发环境,点击发行编译…

C语言 for 循环:解谜数学,玩转生活!

放在最前面的 🎈 🎈 我的CSDN主页:OTWOL的主页,欢迎!!!👋🏼👋🏼 🎉🎉我的C语言初阶合集:C语言初阶合集,希望能…

【专题】2024AIGC创新应用洞察报告汇总PDF洞察(附原数据表)

原文链接:https://tecdat.cn/?p38310 在科技日新月异的今天,人工智能领域正以前所未有的速度发展,AIGC(人工智能生成内容)成为其中最耀眼的明珠。从其应用场景的不断拓展,到对各行业的深刻变革&#xff0…

.NET桌面应用架构Demo与实战|WPF+MVVM+EFCore+IOC+DI+Code First+AutoMapper

目录 .NET桌面应用架构Demo与实战|WPFMVVMEFCoreIOCDICode FirstAutoPapper技术栈简述项目地址:功能展示项目结构项目引用1. 新建模型2. Data层,依赖EF Core,实现数据库增删改查3. Bussiness层,实现具体的业务逻辑4. Service层&am…

两种柑橘物种中WRKY转录因子的鉴定和比较-文献精读82

Genome-wide identification and comparative expression profiling of the WRKY transcription factor family in two Citrus species with different Candidatus Liberibacter asiaticus susceptibility 全基因组范围内鉴定和比较两种对柑橘黄龙病菌(Candidatus …

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)…

vue实现展示并下载后端返回的图片流

// 点击下载 downLoadCode() {const image new Image();image.setAttribute("crossOrigin", "anonymous");image.onload () > {const canvas document.createElement("canvas");canvas.width image.width;canvas.height image.height;c…

c++:模板

1.泛型编程 在认识模板之前,我们首先要认识泛型编程 泛型编程是一种编程范式,它使得算法和数据结构能够独立于特定数据类型进行设计和实现。通过使用泛型,开发者可以编写一次代码,然后在不同的数据类型上进行重用,从…