rrweb录制用户的操作过程,并上传服务端

1、客户端

准备工作,需要使用到的包有rrweb(录制) rrwebPlayer(播放) pako(压缩)

1.1、录制:1.2、pako 压缩工具的使用方式

import * as rrweb from 'rrweb'let dispose = null
let rrwebEvents = []console.log('开始录制 ========>>>>>>>>>>>>>>')
clearFile(); // 录制之前清楚本地缓存json文件
dispose = rrweb.record({emit(event) {rrwebEvents.push(event);// 以 rrwebEvents 的长度作为分片持续上传:if(rrwebEvents.length >= 50) {uploadFile();// 分片之后清空队列:    rrwebEvents = [];}}
})console.log('结束录制 ========>>>>>>>>>>>>>>')
if (dispose) {// 实际场景需要分片传输的话,就不需要这个关闭,当真正业务不需要录制的时候再调用// 分片逻辑是,序列化的rrwebEvents.length的累加大于某个值  --- 分片逻辑看业务需求吧// 我们这里上传的时候是 gzip 后的文件上传,不是用的json方式,也需要后端解gzip,这里只负责演示前端,所以压缩逻辑就没写上// 压缩逻辑是 引入pako, 然后调用,就不体现了哈dispose()
}
if (rrwebEvents.length === 0) return
uploadFile();
rrwebEvents = []

 1.2、pako 压缩工具的使用方式

import pako from 'pako'// 压缩
const data = "Hello, world!";  // 待压缩的数据
const compressedData = pako.deflate(data);  // 使用deflate方法进行压缩
console.log(compressedData);  // 输出压缩后的数据 Uint8Array(21) [120, 156, 243, 72, 205, 201, 201, 215, 81, 40, 207, 47, 202, 73, 81, 4, 0, 32, 94, 4, 138]// 解压
const decompressedData = pako.inflate(compressedData);  // 使用inflate方法进行解压缩
const unData = new TextDecoder().decode(decompressedData);
console.log(unData, '解压');  // 输出解压缩后的数据 Hello, world! 解压

1.3、调用接口

// 接口上传文件
function uploadFile() {console.log('上传文件 ========>>>>>>>>>>>>>>', '\n', rrwebEvents);fetch('http://localhost:8076/upload', {method: 'POST',headers: {'Content-type': 'application/json'},body: JSON.stringify({rrwebEvents})}).then(response => {console.log('response', response)}).catch(error => {console.log('error', error)})
}// 清除文件
function clearFile() {fetch('http://localhost:8076/clearFile', {method: 'POST'}).then(response => {console.log('response', response)}).catch(error => {console.log('error', error)})
}function getFile() {fetch('http://localhost:8076/getFile', {method: 'POST'}).then(response => response.json()).then(data => {new rrwebPlayer({target: document.getElementById('rrwebplayer'),data: {events: data.data,skipInactive: true,showDebug: true,showWarning: true,autoPlay: true}})})
}

2、服务端

使用node的Koa进行开发简易的服务端,使用文件存储的形式

const Koa = require('koa')
const router = require('koa-router')()
const cors = require('koa-cors')
const bodyParser = require('koa-bodyparser')
const fs = require('fs')
const path = require('path')
const app = new Koa()
app.use(cors())
app.use(bodyParser())app.use(router.routes())
app.use(async (ctx, next) => {ctx.set('Access-Control-Allow-Origin', '*')ctx.set('Access-Control-Allow-Headers','Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild')ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS')if (ctx.method == 'OPTIONS') {ctx.body = 200} else {await next()}
})router.post('/upload', ctx => {const jsonFile = path.join(process.cwd(), `./file/jsonFile${Date.now()}.json`)fs.writeFileSync(jsonFile, JSON.stringify(ctx.request.body.rrwebEvents))ctx.response.body = {status: '00'}
})router.post('/getFile', ctx => {const fileDirPath = path.join(process.cwd(), `./file`);const files = fs.readdirSync(fileDirPath);let file;if(files && files.length) {file = fs.readFileSync(`${fileDirPath}/${files[0]}`);}ctx.response.body = {status: '00',data: JSON.parse(file)}
})router.post('/clearFile', ctx => {const fileDirPath = path.join(process.cwd(), `./file`);const files = fs.readdirSync(fileDirPath);if(files && files.length) {files.forEach(item => {const filePath = `${fileDirPath}/${item}`;fs.unlinkSync(filePath);})}ctx.response.body = {status: '00'}
})app.listen(8076)
console.log('listen on 8076')

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

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

相关文章

机械制图(CAD)

目录 第一课(80分钟) 第二课(80分钟) 力啥学机械制图?我们的工厂要加工机械,而加工机械零件前,我们要先给工人图纸来看,工人才知道该怎样加工,所以我们今天就来学习下怎样画出符何…

el-table中点击跳转到详情页的两种方法

跳转的两种写法: 1.使用keep-alive使组件缓存,防止刷新时参数丢失 keep-alive 组件用于缓存和保持组件的状态,而不是路由参数。它可以在组件切换时保留组件的状态,从而避免重新渲染和加载数据。 keep-alive 主要用于提高页面性能和用户体验,而…

element侧边栏子路由点击不高亮问题

最近自己封装侧边栏 又碰到了点击子路由不高亮的问题 <template><div class"aside"><el-scrollbar :vertical"true" class"scrollbar_left_nav"><el-menu :default-active"defaultActive" :collapse"$stor…

亚马逊云科技生成式AI技术辅助教学领域,近实时智能应答2D数字人搭建

早在大语言模型如GPT-3.5等的兴起和被日渐广泛的采用之前&#xff0c;教育行业已经在AI辅助教学领域有过各种各样的尝试。在教育行业&#xff0c;人工智能技术的采用帮助教育行业更好地实现教学目标&#xff0c;提高教学质量、学习效率、学习体验、学习成果。例如&#xff0c;人…

C++基础语法——多态

目录 1.什么是多态&#xff1f; 2.多态的定义与实现 ①多态的构成条件 ②虚函数 ③虚函数的重写 1.协变 2.析构函数的重写 ④final和override 1.final 2.override ⑤重载、重写&#xff08;覆盖&#xff09;与重定义&#xff08;隐藏&#xff09;的区别 3.什么是抽…

QTday3

1.保存文件 void Widget::on_save_clicked() {QString filename QFileDialog::getSaveFileName(this,"选择文件","F:\\study\\huaqing\\save","Text File(*.txt)");if(filename.isNull()){QMessageBox::information(this,"提示",&qu…

苹果macOS 14开发者预览版Beta 7发布 新增超过100款视频壁纸和屏保

8 月 31 日&#xff0c;苹果向 Mac 电脑用户推送了 macOS 14 开发者预览版 Beta 7 更新&#xff08;内部版本号&#xff1a;23A5337a&#xff09;&#xff0c;本次更新距离上次发布隔了 8 天。 苹果发布 Beta 7 更新的同时&#xff0c;还发布了第 6 个公测版&#xff0c;正式版…

性能测试(测试系列10)

目录 前言&#xff1a; 1.什么是性能测试 1.1生活中遇到的软件问题 1.2性能测试的定义 1.3性能测试和功能测试有什么区别 1.4性能的好坏的区分 1.5影响一个软件性能的因素 2.为什么要进行性能测试 3.性能测试常见的术语以及衡量指标 3.1并发 3.2用户数 3.3响应时间 …

神经网络--感知机

感知机 单层感知机原理 单层感知机:解决二分类问题&#xff0c;激活函数一般使用sign函数,基于误分类点到超平面的距离总和来构造损失函数,由损失函数推导出模型中损失函数对参数 w w w和 b b b的梯度&#xff0c;利用梯度下降法从而进行参数更新。让1代表A类&#xff0c;0代…

关于异或的小疑惑

今天写c&#xff0c;当我写出如下代码时&#xff0c;编译器报错了 #include<bits/stdc.h>using namespace std;int main(){int a1,b3,c2,d6;// cout<<(a^b^c^d)<<endl;cout<<a^b^c^d<<endl;return 0; } D:\sublineText\demo\demo.cpp: In funct…

C++ do...while 循环

不像 for 和 while 循环&#xff0c;它们是在循环头部测试循环条件。do…while 循环是在循环的尾部检查它的条件。 do…while 循环与 while 循环类似&#xff0c;但是 do…while 循环会确保至少执行一次循环。 语法 C 中 do…while 循环的语法&#xff1a; do {statement(s…

煤矿监管电子封条算法

煤矿监管电子封条算法基于yolov5网络模型深度学习框架&#xff0c;先进技术的创新举措&#xff0c;煤矿监管电子封条算法通过在现场运料运人井口、回风井口、车辆出入口等关键位置进行人员进出、人数变化和设备开停等情况的识别和分析。YOLO检测速度非常快。标准版本的YOLO可以…

MongoDB 的简介

MongoDB 趋势 对于 MongoDB 的认识 Q&A QA什么是 MongoDB&#xff1f; 一个以 JSON 为数据模型的文档数据库一个以 JSON 为数据模型的文档数据库文档来自于“JSON Document”&#xff0c;并非我们一般理解的 PDF&#xff0c;WORD谁开发 MongDB&#xff1f; 上市公司 MongoD…

SpringBoot核心原理与实践

第一章、SpringBoot简介 1、入门案例 2、官网创建压缩包程序 注意使用的版本pom文件中java --> 1.8、 springboot --> 2.5.0 3、SpringBoot快速启动 运行程序--找引导类 换技术、加技术--加starter 第二章、基础配置 1、配置文件格式 《1、端口号配置》 《2、将目录文…

DOCKER 部署 webman项目

# 设置基础镜像 FROM php:8.2-fpm# 安装必要的软件包和依赖项 RUN apt-get update && apt-get install -y \nginx \libzip-dev \libpng-dev \libjpeg-dev \libfreetype6-dev \&& rm -rf /var/lib/apt/lists/*# 安装 PHP 扩展 RUN docker-php-ext-configure gd …

leetcode 84. 柱状图中最大的矩形

2023.8.30 本题和接雨水 有点类似&#xff0c;依旧用双指针来解。但是本题要记录的是当前柱子 左右两侧第一个小于该柱子的索引。将其保存在两个数组中&#xff0c;最后再求最大面积。代码如下&#xff1a; class Solution { public:int largestRectangleArea(vector<int&g…

STM32f103入门(10)ADC模数转换器

ADC模数转换器 ADC简介AD单通道初始化代码编写第一步开启时钟第二步 RCCCLK分频 6分频 72M/612M第三步 配置GPIO 配置为AIN状态第四步&#xff0c;选择规则组的输入通道第五步 用结构体 初始化ADC第六步 对ADC进行校准编写获取电压函数初始化代码如下 Main函数编写 ADC简介 ADC…

AcWing 4405. 统计子矩阵(每日一题)

如果你觉得这篇题解对你有用&#xff0c;可以点点关注再走呗~ 题目描述 给定一个 NM 的矩阵 A&#xff0c;请你统计有多少个子矩阵 (最小 11&#xff0c;最大 NM) 满足子矩阵中所有数的和不超过给定的整数 K ? 输入格式 第一行包含三个整数 N,M 和 K。 之后 N 行每行包含 …

软件过程模型

软件过程模型 软件过程模型习惯上称为软件开发模型&#xff0c;它是软件开发全部过程、活动和任务的结构框架。典型的软件过程有瀑布模型、增量模型、演化模型&#xff08;原型模型、螺旋模型&#xff09;、喷泉模型、基于构件的开发模型和形式化方法模型等。 1. 瀑布模型 瀑…

DRM全解析 —— ADD_FB(2)

接前一篇文章&#xff1a;DRM全解析 —— ADD_FB&#xff08;1&#xff09; 本文参考以下博文&#xff1a; DRM驱动&#xff08;四&#xff09;之ADD_FB 特此致谢&#xff01; 上一回围绕libdrm与DRM在Linux内核中的接口&#xff1a; DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, d…