webSocket TS 类封装,包含心跳机制,以及断线重连

/**
 * @author yang
 * @description socket封装
 * @time 2021/11/1
 * */
interface Ioptions {
    // token
    token?: string;
    // 发送心跳间隔时间
    heart_time?: number;
    //检查链接状态时间
    check_time?: number;
    //断线后重连间隔时间
    lock_time?: number;
}

let createSocket = (url: string, callback: (e: any) => void) => {

    class Ws {
        private url: string = url //socket 地址
        private callback: (e: any) => void = callback
        private heart_time: number = 3000 //心跳时间
        private check_time: number = 3000 //检查链接状态时间
        private lock_time: number = 4000 //重连时间
        public ws: WebSocket | undefined  //socket实例
        private h_timer: NodeJS.Timeout | undefined //心跳定时器
        private c_timer: NodeJS.Timeout | undefined //检查链接定时器
        private l_timer: NodeJS.Timeout | undefined //重连定时器
        private isLock: boolean = false //重连锁
        private token: string | undefined //token


        public init(options: Ioptions = {}): void {

            let { token, heart_time, check_time, lock_time } = options

            if (token) {
                this.token = token
            }

            if (heart_time) {
                this.heart_time = heart_time
            }

            if (check_time) {
                this.check_time = check_time
            }

            if (lock_time) {
                this.lock_time = lock_time
            }

            if (this.url == '') {
                throw new Error('socket链接地址不能为空')
            }

            this.wsInit()
        }

        // 处理有token时的socket链接地址
        private getUrl(): string {
            if (this.token !== undefined) {
                return `${this.url}?token=${this.token}`
            } else {
                return `${this.url}`
            }
        }

        // 初始化socket
        public wsInit(): void {
            let ws = new WebSocket(this.getUrl())

            ws.onopen = () => {
                this.heartCheck()
            }

            ws.onclose = () => {
                this.reconnect()
            }

            ws.onerror = () => {
                this.reconnect()
            }

            ws.onmessage = (e) => {
                this.heartCheck()
                this.callback(e)
            }

            this.ws = ws
        }

        // 心跳
        private heartCheck(): void {
            this.h_timer && clearTimeout(this.h_timer)
            this.c_timer && clearTimeout(this.c_timer)
            this.h_timer = setTimeout(() => {
                (this.ws as WebSocket).send('type:ping')
                this.c_timer = setTimeout(() => {
                    if ((this.ws as WebSocket).readyState !== 1) {
                        (this.ws as WebSocket).close()
                    }
                }, this.check_time)
            }, this.heart_time)
        }

        // 重连
        private reconnect(): void {
            if (this.isLock) {
                return
            }

            this.isLock = true
            this.l_timer && clearTimeout(this.l_timer)
            this.l_timer = setTimeout(() => {
                this.wsInit()
                this.isLock = false
            }, this.lock_time)
        }
    }

    return new Ws
}

export {
    createSocket
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值