JS websocket工具类

/**
 * @desc websocket 工具类
 * @param url 连接url
 * @param callback 接收消息回调函数
 * @param config 配置项:
 *                  reconnectCount: 3 (重连次数,默认3次)
 *                  reconnentInterval: 3000 (重连间隔,默认3秒)
 *                  resendMessageCount: 3 (重发消息次数,默认3次)
 *                  resendMessageInterval: 1000 (重发消息间隔,默认1秒)
 *                  heartBeatInterval: 5000 (心跳间隔时长,默认5秒)
 *                  onOpen: Function (连接成功回调)
 *                  onClose: Function (连接关闭回调)
 *                  onError: Function (连接错误回调)
 * @auth Roffer
 * @date 2022/5/13 15:01
 *
 */
export default class Socket {
    constructor(url, callback, config = {}) {
        this.option = {
            //重连次数,默认3次
            reconnectCount: 3,
            //重连间隔,默认3秒
            reconnentInterval: 3000,
            //重发消息次数,默认3次
            resendMessageCount: 3,
            //重发消息间隔,默认1秒
            resendMessageInterval: 1000,
            //心跳间隔时长,默认5秒
            heartBeatInterval: 5000,
            //连接成功回调
            onOpen(){},
            //连接关闭回调
            onClose(){},
            //连接错误回调
            onError(){},
            ...config
        }

        //链接地址(不带ws://)
        this.url = url
        //回调函数
        this.callback = callback || ((data) => {
        })

        //实例
        this.instance = null
        //是否连接中
        this.isConnecting = false
        //心跳定时器对象,断开时清除
        this.__heartBeatIntervalInstance = null

        this.__reconnectCount = this.option.reconnectCount
        this.__resendMessageCount = this.option.resendMessageCount
        this.__heartBeatInterval = this.option.heartBeatInterval
        this.__reconnentInterval = this.option.reconnentInterval
        this.__resendMessageInterval = this.option.resendMessageInterval
        //是否已连接
        this.isConnected = false

        this.connect()
    }

    /** 初始化连接 **/
    connect() {
        this.__reconnectCount--
        this.isConnecting = true
        let instance = new WebSocket(this.url)

        instance.onmessage = (e) => {
            this.callback instanceof Function && this.callback(e.data)
        }

        instance.onclose = (e) => {
            console.log('连接关闭!')
            this.isConnected = false
            this.__reset()
            this.option.onClose(e)
        }

        instance.onopen = (e) => {
            console.log('连接成功!')
            this.isConnected = true
            this.__reset()
            //连接成功,执行心跳连接,保持连接通畅
            this.__heartBeat()

            this.option.onOpen(e)
        }

        instance.onerror = (e) => {
            console.log('连接失败!')
            this.isConnecting = false
            this.isConnected = false
            setTimeout(() => {
                this.__reconnect()
            }, this.__reconnentInterval)
            this.option.onError(e)
        }

        this.instance = instance
    }

    /** 发送消息到服务端 **/
    sendMessage(data) {
        return new Promise((resolve, reject) => {
            const send = () => {
                if (this.instance.readyState == this.instance.OPEN) {
                    let params = typeof data === 'string' ? data : JSON.stringify(data)
                    this.instance.send(params)
                    //发送成功,将重发次数重置
                    this.__resendMessageCount = this.option.resendMessageCount
                    resolve({code: 200, message: '发送成功'})
                } else {
                    if (this.__resendMessageCount === 0) {
                        this.__resendMessageCount = this.option.resendMessageCount
                        //如果3次都没有发送成功,说明连接断开,进行重连
                        this.__reconnect()
                        reject({code: 500, message: '连接失败'})
                    } else {
                        setTimeout(() => {
                            send()
                        }, this.__resendMessageInterval)
                        this.__resendMessageCount--
                    }
                }
            }
            send()
        })
    }

    /** 断开连接 **/
    close() {
        this.instance && this.instance.close()
    }

    /** 重置参数 */
    __reset(){
        this.__reconnectCount = this.option.reconnectCount
        this.__resendMessageCount = this.option.resendMessageCount
        this.isConnecting = false
        //清除心跳定时器
        this.__heartBeatIntervalInstance && clearInterval(this.__heartBeatIntervalInstance)
    }

    /** 重连 */
    __reconnect() {
        if (!this.isConnecting && this.instance.readyState !== this.instance.OPEN && this.__reconnectCount > 0) {
            this.connect()
        }
    }

    /** 心跳连接 */
    __heartBeat() {
        this.__heartBeatIntervalInstance && clearInterval(this.__heartBeatIntervalInstance)
        this.__heartBeatIntervalInstance = setInterval(() => {
            this.sendMessage({isHeartBeat: true})
        }, this.__heartBeatInterval)
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

roffer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值