rrweb

2023-12-13  本文已影响0人  人间四月天i
import * as rrweb from 'rrweb';
import axios from 'axios';

export class Rrweb {

    constructor(ucid) {
        this.rrwebList = [];
        this.timer = null;
        this.isRecordFlag = true;
        this.recordId = null;
        this.ucid = ucid;
        this.startEventSource();
        this.promiseChain = Promise.resolve();
    }
    // 设置并启动定时器
    setAndStartTimer(isLast) {
        if (this.timer) {
            clearInterval(this.timer);
        }
        if (isLast || this.timer) {
            return;
        }
        this.promiseChain = new Promise((resolve, reject) => {
            this.timer = setInterval(async () => {
                try {
                    await this.uploadFile();
                    resolve();
                } catch (err) {
                    reject(err);
                }
            }, 60000);
        });
    }

    // 上传文件
    async uploadFile() {
        if (this.rrwebList.length <= 0 || !this.recordId) {
            return;
        }
        try {
            const res = await axios({
                url: '/upload',
                method: 'post',
                data: {
                    recordJson: this.rrwebList,
                    recordId: this.recordId,
                    ucid: this.ucid,
                },
                headers: {
                    'Content-Type': 'application/json',
                },
            });
            if (res.data && res.data.code !== 0) {
                this.stop();
            }
            else {
                clearInterval(this.timer);
                this.rrwebList = [];
                this.setAndStartTimer(false);
            }
        }
        catch (err) {
            // this.stop();
            console.log(err, 'err');
        }
    }

    // 开始录制
    start() {
        this.rrwebList = [];
        this.setAndStartTimer(false);
        this.stopFn = rrweb.record({
            emit: event => {
                this.rrwebList.push(event);
            },
            sampling: {
                // 不录制鼠标移动事件
                mousemove: false,
                // 不录制鼠标交互事件
                // mouseInteraction: false,
                // 设置滚动事件的触发频率
                scroll: 250, // 每 250ms 最多触发一次
                media: 800,
                input: 'last', // 连续输入时,只录制最终值
                mouseInteraction: {
                    MouseUp: false,
                    MouseDown: false,
                    ContextMenu: false,
                    DblClick: false,
                    Focus: false,
                    Blur: false,
                    TouchStart: false,
                    TouchEnd: false,
                },
            },
            inlineImages: true,
            // recordCanvas: true,
            recordCrossOriginIframes: true,
            packFn: rrweb.pack,
            blockClass: 'agent-bar-nav',
        });
    }

    // 停止录屏
    async stop() {
        this.stopFn && this.stopFn();
        clearInterval(this.timer);
        this.setAndStartTimer(true);
        await this.handleUploadError();
        this.rrwebList = [];
    }

    startEventSource() {
        const eventSource = new EventSource(`/start?ucid=${this.ucid}`);
        eventSource.onmessage = even => {
            this.handleMessage(even.data);
        };
        eventSource.onerror = err => {
            this.handleError(err);
        };
    }

    handleMessage(data) {
        let message = JSON.parse(data);
        this.recordId = message.recordId;
        if (message.isRecord === 1 && this.isRecordFlag) {
            this.start();
            this.isRecordFlag = false;
        }
        else if (message.isRecord === 0) {
            this.stop();
            this.isRecordFlag = true;
        }
    }

    // 处理错误
    async handleError(err) {
        if (this.recordId) {
            await this.promiseChain;
            await this.handleUploadError();
            this.start();
        }
        else {
            this.stop();
        }
        console.error(err, '连接已断开');
    }

    handleUploadError() {
        return this.uploadFile();
    }
}

上一篇下一篇

猜你喜欢

热点阅读