webSocket TS 類封裝,包含心跳機制,以及斷線重連


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
}


未測試


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM