zoukankan      html  css  js  c++  java
  • WebSocket 的简单用法

    // 与服务器定义的返回字段信息
    enum SocketEvents {
        taken_offline = "taken_offline"
    }
    
    export { SocketEvents }
    
    interface SocketEvent {
        event: SocketEvents,
        message: string,
        data: any
    }
    
    type SocketEventListener = (event: SocketEvent) => void
    
    type removeEventListen = () => void
    
    /**
     *  创建一个websocket的构造函数! 结合发布订阅模式
     */
    class SocketManager {
        private socket!: WebSocket
        private socketListeners = new Set<SocketEventListener>()
        private isConnect = false
        private isTimeout = false
        private keepAliveTimeInterval!: NodeJS.Timeout
        private checkTimeoutTimer!: NodeJS.Timeout
        private reTryTimes = 0 // 重连次数
    
        public async start() {
            // 设置需要建立联系的地址
            let cashierWssAddress = ""
            if (process.env.NODE_ENV === "development") {
                cashierWssAddress = "https://xxxx.xxxx.xx".replace('https', "wss")
            } else {
                cashierWssAddress = '生成环境地址'.replace('https', "wss")
            }
    
            this.socket = new WebSocket(cashierWssAddress)
            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)
        }
    
        public stop() {
            if (this.socket) {
                this.socket.close()
            }
            clearInterval(this.checkTimeoutTimer)
            clearInterval(this.keepAliveTimeInterval)
        }
    
        public addEventListener(fn: SocketEventListener): removeEventListen {
            this.socketListeners.add(fn)
    
            return () => {
                this.socketListeners.delete(fn)
            }
        }
    
        public removeEventListener(fn: SocketEventListener) {
            this.socketListeners.delete(fn)
        }
    
        private onOpen(event: Event) {
            console.log('socket 建立连接')
            this.isConnect = true
            this.reTryTimes = 0
            this.keepAlive()
        }
    
        private onMessage(event: MessageEvent) {
            const data = JSON.parse(event.data)
            console.log('socket 收到消息', data)
            this.dispathEvent(data)
    
            if (this.checkTimeoutTimer) {
                clearTimeout(this.checkTimeoutTimer)
            }
            this.isTimeout = false
            this.checkTimeoutTimer = setTimeout(() => {
                if (this.isConnect) {
                    this.isTimeout = true
                    console.log('socket 连接超时')
                }
            }, 40 * 1000)
        }
    
        private onError(event: Event) {
            if (this.reTryTimes < 5) {
                console.log("连接失败")
            } else {
                console.log('socket 通信错误', event)
                this.isConnect = false
                // openMessage(MessageType.error, "socket连接失败,将无法使用系统")
                setTimeout(() => {
                    // System.logout().then(() => {
                    //     window.location.href = PASSPORT_DOMAIN + '/#/login?oa=new_ls'
                    // })
                }, 3 * 1000)
            }
        }
    
        private onClose(ev: CloseEvent) {
            console.log('socket 连接关闭')
            this.isConnect = false
            if (this.reTryTimes < 5) {
                this.reTryTimes++
                // openMessage(MessageType.info, "socket 断开连接,尝试第" + this.reTryTimes + "次重连")
                setTimeout(() => {
                    this.start()
                }, 3 * 1000)
            }
        }
    
        private keepAlive() {
            clearInterval(this.keepAliveTimeInterval) // 防止重复调用
            this.keepAliveTimeInterval = setInterval(() => {
                if (!this.isConnect) {
                    return clearInterval(this.keepAliveTimeInterval)
                }
                if (this.isTimeout) {
                    return this.start()
                }
    
                if (this.socket) {
                    this.socket.send('❤️')
                } else {
                    clearInterval(this.keepAliveTimeInterval)
                }
            }, 10 * 1000)
        }
    
        private dispathEvent(event: SocketEvent) {
            this.socketListeners.forEach(fn => fn(event))
        }
    }
    
    const socketManager = new SocketManager()
    
    socketManager.addEventListener((socketEvent) => {
    
        switch (socketEvent.event) {
            case SocketEvents.taken_offline:
                // reactHistory.push("/noSeat")
                break
        }
    })
    
    
    export {
        socketManager
    }
    
    
  • 相关阅读:
    [BZOJ2434][Noi2011]阿狸的打字机
    [BZOJ2303][Apio2011]方格染色
    [BZOJ1912][Apio2010]patrol 巡逻
    [BZOJ1179][Apio2009]Atm
    [BZOJ1178][Apio2009]CONVENTION会议中心
    Lock-less buffer management scheme for telecommunication network applications
    vue-router@2.x 只适用于 Vue 2.x 版本。
    jQuery 捕获
    jQuery Chaining
    jQuery Callback 方法
  • 原文地址:https://www.cnblogs.com/yaogengzhu/p/13617260.html
Copyright © 2011-2022 走看看