开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 2700|回复: 19
收起左侧

[Web源码] 高质量纯源 Websocket js版本

[复制链接]
头像被屏蔽
结帖率:100% (4/4)
发表于 2024-5-10 09:40:28 | 显示全部楼层 |阅读模式   安徽省马鞍山市
分享源码
界面截图: -
是否带模块: -
备注说明: -
本帖最后由 盖伦总管 于 2024-5-10 09:47 编辑

// 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.options.maxReconnectAttempts) {
            this.options.logFunction(`Attempting to reconnect... (attempt ${this.reconnectAttempts + 1} of ${this.options.maxReconnectAttempts})`);
            this.reconnectTimer = setTimeout(() => {
                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');
        }
    }
}

评分

参与人数 3精币 +3 收起 理由
wa690602724 + 1 感谢分享,很给力!~
多多帅吧 + 1 此处应该有鼓励~
財財 + 1 感谢分享,很给力!~

查看全部评分


发表于 2024-5-30 12:45:21 | 显示全部楼层   四川省德阳市
        感谢分享,很给力!~
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)

签到天数: 4 天

发表于 2024-5-18 18:19:03 | 显示全部楼层   广东省江门市
很厉害  谢谢
回复 支持 反对

使用道具 举报

签到天数: 28 天

发表于 2024-5-13 16:34:53 | 显示全部楼层   河南省郑州市
支持开源~!感谢分享
回复 支持 反对

使用道具 举报

结帖率:0% (0/2)

签到天数: 25 天

发表于 2024-5-12 09:16:02 | 显示全部楼层   广西壮族自治区玉林市
谢谢分享!
回复 支持 反对

使用道具 举报

签到天数: 7 天

发表于 2024-5-12 01:56:45 | 显示全部楼层   浙江省温州市
开源精神必须支持~
回复 支持 反对

使用道具 举报

结帖率:33% (1/3)
发表于 2024-5-11 20:34:58 | 显示全部楼层   广东省深圳市
支持开源~!感谢分享
回复 支持 反对

使用道具 举报

结帖率:73% (8/11)

签到天数: 25 天

发表于 2024-5-11 13:12:25 | 显示全部楼层   河南省焦作市

谢谢分享~~
回复 支持 反对

使用道具 举报

结帖率:0% (0/2)

签到天数: 25 天

发表于 2024-5-11 08:54:12 | 显示全部楼层   广西壮族自治区玉林市
感谢分享,很给力!~
回复 支持 反对

使用道具 举报

结帖率:100% (4/4)

签到天数: 27 天

发表于 2024-5-11 08:00:05 | 显示全部楼层   山东省淄博市
感谢分享
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表