// WebSocket封装类,提供WebSocket连接的管理和控制

class Socket {
    constructor(options) {
        // 初始化实例变量
        this.socket;
        this.options = {
            url: '', // WebSocket服务器的URL
            onopen: null, // 连接建立时的回调函数
            onmessage: null, // 接收消息时的回调函数
            onerror: null, // 连接错误时的回调函数
            onclose: null, // 连接关闭时的回调函数
            reconnectDelay: 3000, // 重新连接延迟时间(毫秒)
            pingInterval: 14000, // 发送ping消息的间隔时间(毫秒)
            maxReconnectAttempts: 5, // 最大重新连接尝试次数
            logFunction: console.log, // 日志函数,默认为console.log
            isErrorReconnect: true, // 是否在错误发生时重新连接
            ...options // 其他用户提供的选项
        };
        this.errorStack = []; // 发送失败消息的堆栈
        this.reconnectTimer = null; // 重新连接计时器
        this.pingInterval = null; // ping消息间隔计时器
        this.reconnectAttempts = 0; // 当前重新连接尝试次数
        this.isCustomClose = false; // 是否由用户手动关闭连接
        // 连接WebSocket
        this.connect();
    }

    connect() {
        if ('WebSocket' in window) {
            try {
                // 尝试连接WebSocket服务器
                this.options.logFunction('Attempting to connect to WebSocket server');
                this.socket = new WebSocket(this.options.url);
                this.socket.onopen = this.onopen.bind(this);
                this.socket.onmessage = this.onmessage.bind(this);
                this.socket.onerror = this.onerror.bind(this);
                this.socket.onclose = this.onclose.bind(this);
            } catch (error) {
                // 连接异常,尝试重新连接
                console.error('WebSocket Error:', error);
                this.reconnect();
            }
        } else {
            console.error('WebSocket not supported');
        }
    }

    // 连接建立时的回调函数
    onopen() {
        this.options.logFunction('WebSocket connection established');
        // 发送堆栈中的所有消息
        this.errorStack.forEach(message => this.send(message));
        this.errorStack = [];
        this.setupPingInterval(); // 设置ping消息发送间隔
        if (this.options.onopen) this.options.onopen();

        // 重置重新连接尝试次数
        this.reconnectAttempts = 0;
    }

    // 接收消息时的回调函数
    onmessage(event) {
        if (event.data instanceof ArrayBuffer || event.data instanceof Blob) {
            // 接收到二进制数据,将其视为心跳消息
            this.options.logFunction('Heartbeat received');
            return;
        }

        this.options.logFunction('Message received:', event.data);
        let parsedMessage;
        try {
            parsedMessage = JSON.parse(event.data);
        } catch (error) {
            // 非JSON数据,根据需要处理
            parsedMessage = event.data;
        }
        if (this.options.onmessage) this.options.onmessage(parsedMessage);
    }

    // 连接错误时的回调函数
    onerror(error) {
        console.error('WebSocket error:', error);
        if (this.options.onerror) this.options.onerror(error);
        if (this.options.isErrorReconnect && this.socket.readyState !== WebSocket.CLOSED) this.reconnect();
    }

    // 连接关闭时的回调函数
    onclose(event) {
        this.options.logFunction('WebSocket connection closed:', event.code, event.reason);
        if (this.options.onclose) this.options.onclose(event);
        if (!this.isCustomClose) this.reconnect();
    }

    // 发送消息
    send(message) {
        if (this.socket && this.socket.readyState === WebSocket.OPEN) {
            let msgToSend = message;
            if (typeof message === 'object') {
                try {
                    msgToSend = JSON.stringify(message);
                } catch (error) {
                    console.error('Error converting object to JSON:', error);
                    return;
                }
            }
            this.options.logFunction('Sending message:', msgToSend);
            this.socket.send(msgToSend);
        } else {
            this.errorStack.push(message);
        }
    }

    // 设置ping消息发送间隔
    setupPingInterval() {
        if (!this.pingInterval) {
            this.pingInterval = setInterval(() => {
                if (this.socket.readyState === WebSocket.OPEN) {
                    this.options.logFunction('Sending ping');
                    const pingData = new Uint8Array([0x70, 0x69, 0x6E, 0x67]).buffer;
                    this.socket.send(pingData);
                }
            }, this.options.pingInterval);
        }
    }

    // 关闭连接
    close() {
        if (this.socket && !this.isCustomClose && this.socket.readyState === WebSocket.OPEN) {
            this.options.logFunction('Closing WebSocket connection');
            this.socket.close();
        }
    }

    // 重新连接
    reconnect() {
        if (this.reconnectAttempts < this xss=removed xss=removed> {
                this.connect();
                this.reconnectAttempts++;
            }, this.options.reconnectDelay);
        } else {
            this.options.logFunction('Max reconnection attempts reached. Stopping further attempts.');
        }
    }

    // 销毁实例
    destroy() {
        if (this.socket) {
            this.isCustomClose = true;
            this.close();
            this.socket = null;
            this.errorStack = [];
            clearInterval(this.pingInterval);
            clearInterval(this.reconnectTimer);
            this.options.logFunction('WebSocket instance destroyed');
        }
    }
}

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部