vue2 websocket配置 混入

 1. 在mixins文件夹下写入websocket.js配置文件

思路:初始化时可以传入一个ws接口,也可以手动配置,如果当前支持ws,则开启ws以及其相关的监听:onopen连接成功,onclose连接关闭,onerror连接错误,onmessage返回消息,init时传入一个函数,在获取数据后把数据传入函数,然后调用此函数以方便操作数据

export default {
    data() {
        return {
            socket: '', //WebSocket
        }
    },
    destroyed() {
        this.closeWebsocket();
    },
    methods: {
        initWebSocket(fn,url) {
            let weburl = url || this.webSocketUrl
            if (!window.WebSocket) { return }
            if (!this.socket) {
                this.socket = new WebSocket(weburl)
                this.socketOnOpen()
                this.socketOnClose()
                this.socketOnError()
                this.socketOnMessage(fn)
            }
        },
        /**
         * 关闭websocket
         */
        closeWebsocket() {
            if (this.socket) {
                this.socket.close()
            }
        },
        socketOnSend(data) {
            this.socket.send(data)
        },
        socketOnOpen() {
            this.socket.onopen = () => {
                console.log('连接成功!')
                this.socketOnSend('连接成功')
            }
        },
        socketOnClose() {
            this.socket.onclose = () => {
                console.log('ws已经关闭')
            }
        },
        socketOnError() {
            this.socket.onerror = () => {
                console.log('ws连接失败')
            }
        },
        socketOnMessage(fn) {
            this.socket.onmessage = (e) => {
                console.log('返回消息');
                fn(JSON.parse(e.data))
            }
        },
    },
}

2.使用:引用,初始化,获得数据

import wsMixin from '@/mixins/websocket.js'
export default {
  mixins: [websocketMixin],
  created() {
    this.webSocketUrl = `接口`
    this.initWebSocket(this.callback) //初始化
  },
    methods:{
        callback(data){
            console.log(data) //操作返回的数据
        }
    }
    
}

有心跳的ws

组件destroyed的时候关闭ws

组件created的时候初始化ws:

  • 判断浏览器是否支持,判断当前组件是否有ws实例了
  • 开启open,close,error,message监听
  • open:连接成功开启心跳
  • close:log已经关闭
  • error:连接失败启动重连
  • message:收到消息,传给回调函数,如果是心跳就重置心跳
  • 开启心跳:如果有心跳定时器就清除,定义一个心跳周期定时器,如果readyState是1就发送‘heartbeat’否则就重连,发送心跳后定义一个定时器,如果超时未响应就关闭
  • 重置心跳:清除两个定时器,重新开启心跳
  • 重连心跳:清除定时器,五秒后初始化ws,定义变量--如果当前没有在重连才会再次初始化
export default {
    data() {
        return {
            socket: '', //WebSocket
            lockReconnect: false, // 是否真正建立连接
            heartbeatTimeCycle: 20 * 1000, // 定义心跳周期默认为20s
            timeoutObj:'', //心跳心跳倒计时
            serverTimeoutObj: '', //心跳倒计时
            timeoutNum:'',
        }
    },
    destroyed() {
        this.closeWebsocket()
    },
    methods: {
        initWebSocket(fn, url) {
            let weburl = url || this.webSocketUrl
            if (!window.WebSocket) { return }
            if (!this.socket) {
                this.socket = new WebSocket(weburl)
                this.socketOnOpen()
                this.socketOnClose()
                this.socketOnError()
                this.socketOnMessage(fn)
            }
        },
        /**
         * 关闭websocket
         */
        closeWebsocket() {
            if (this.socket) {
                this.socket.close()
            }
        },
        socketOnSend(data) {
            if (this.socket.readyState == 1)
                this.socket.send(data)
        },
        socketOnOpen() {
            this.socket.onopen = () => {
                console.log('连接成功!')
                this.startHeartbeat();
            }
        },
        socketOnClose() {
            this.socket.onclose = () => {
                console.log('ws已经关闭')
            }
        },
        socketOnError() {
            this.socket.onerror = () => {
                console.log('ws连接失败')
                this.reconnect()
            }
        },
        socketOnMessage(fn) {
            this.socket.onmessage = (e) => {
                if (e.data.includes("heartbeat")) {
                    // 在心跳周期内收到后端消息, 则重置心跳
                    this.resetHeartbeat();
                } else {
                    // 把后端返回值给回调函数
                    console.log("收到来自后端的数据");
                    fn(JSON.parse(e.data))
                }
            }
        },
        // 开启心跳
        startHeartbeat() {
            this.timeoutObj && clearTimeout(this.timeoutObj);
            this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
            console.log("开启心跳---心跳周期:(毫秒)", this.heartbeatTimeCycle);
            this.timeoutObj = setTimeout(() => {
                // 如果连接正常
                if (this.socket.readyState == 1) {
                    // 这里发送一个心跳,后端收到后,返回一个心跳消息
                    this.socket.send('{"heartbeat":"heartbeat"}');
                    console.log('发送心跳');
                } else {
                    // 否则重连
                    this.reconnect();
                }
                this.serverTimeoutObj = setTimeout(() => {
                    // 超时关闭
                    console.log("心跳超时未响应---", this.heartbeatTimeCycle);
                    this.socket.close();
                }, this.heartbeatTimeCycle);
            }, this.heartbeatTimeCycle);
        },
        resetHeartbeat() {
            //清除时间
            clearTimeout(this.timeoutObj);
            clearTimeout(this.serverTimeoutObj);
            //重启心跳
            this.startHeartbeat();
        },
        reconnect() {
            if (this.lockReconnect) {
                return;
            }
            this.lockReconnect = true;
            //没连接上会一直重连,设置延迟避免请求过多
            this.timeoutNum && clearTimeout(this.timeoutNum);
            this.timeoutNum = setTimeout(() => {
                //新连接
                console.log('尝试重连',this.socket);
                this.initWebSocket(this.global_callback);
                this.lockReconnect = false;
            }, 5000);
        }

    },
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值