BOYYANG/1/blog/完美世界 清漪 同人 唯美 4k壁纸图片_彼岸图网

websocket封装(断线重连,心跳)

作者: boyyang
分类: 前端开发
发布: 2024-04-18 14:29:29
更新: 2025-03-31 05:53:53
浏览: 182


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
}



#前端
#javascript
#websocket