vue + websocket 的坑

记录一下在开发过程中的坑,不封装,没有插件,不使用vuex,纯小白写法(我就是小白本人)

本内容分为自己搭的测试环境和后端对接两个部分

因为一些原因,要保持与服务端的同步,然后使用了websocket,不说废话,上代码。(其实我觉得每1秒请求一次接口也行,但是考虑到实时性的问题,em…)

1. 自己搭建的node环境

在这里插入图片描述每500毫秒给用户推送消息

自己搭建的node环境的前端测试代码:


  created() {
    //页面刚进入时开启长连接
    this.initWebSocket();
  },
  destroyed: function() {
    //页面销毁时关闭长连接
    this.websocketclose();
  },
  methods: {
    initWebSocket() {
      //初始化weosocket
      const wsuri = "ws://localhost:3000"; //ws地址
      this.$websocket = new WebSocket(wsuri);
      this.$websocket.onopen = this.websocketonopen;
      this.$websocket.onerror = this.websocketonerror;
      this.$websocket.onmessage = this.websocketonmessage;
      this.$websocket.onclose = this.websocketclose;
    },
    websocketonopen() {
      console.log("WebSocket连接成功");
    },
    websocketonerror(e) {
      //错误
      console.log("WebSocket连接发生错误");
      this.initWebSocket();
    },
    websocketonmessage(e) {
      //数据接收
      console.log(e);
      this.msg = e.data;
    },
    websocketsend(agentData) {
      //数据发送
      this.$websocket.send(agentData);
    },
    websocketclose(e) {
      //关闭
      console.log("connection closed (" + e.code + ")");
    }
  }

在这里插入图片描述连接成功,数据也能收到

然后,当服务断开后会不断重连,

在这里插入图片描述然后重点来了,我再来开启服务:
在这里插入图片描述会看到,不管重连多少次,他总是返回一条,只有一条 “连接成功”的字样

2. 但是在真实的项目中…

(项目代码和之前写的代码一样,就是加了点逻辑)


    created() {

        //页面刚进入时开启长连接
        this.initWebSocket();
        }
    },
    destroyed: function() {
        //页面销毁时关闭长连接
        this.websocketclose();
    },
    methods: {
        asd(){
            console.log(123)
        },
        initWebSocket() {
            // console.log(this.BASE_URL_WS)
            //初始化weosocket
            const wsuri = this.BASE_URL_WS; //ws地址
            this.$websocket = new WebSocket(wsuri);
            this.$websocket.onopen = this.websocketonopen;
            this.$websocket.onerror = this.websocketonerror;
            this.$websocket.onmessage = this.websocketonmessage;
            this.$websocket.onclose = this.websocketclose;
        },
        websocketonopen() {
            console.log("WebSocket连接成功");
        },
        websocketonerror(e) {
            //错误
            this.initWebSocket();
            console.log("WebSocket连接发生错误");
        },
        websocketonmessage(e) {
            console.log(e);
            //数据接收
            if(e !== undefined){
                console.log(e);
                this.msg = e.data;
                var json = JSON.parse(e.data);
                this.setCache('carOut',json )
                
            }
        },
        websocketsend(agentData) {
            //数据发送
            this.$websocket.send(agentData);
        },
        websocketclose(e) {
            //关闭
            this.initWebSocket();
            // console.log("connection closed (" + e.code + ")");
        },

然后连上服务器,再断开,等个几秒让他重连,再连上你就会发现。。。。
在这里插入图片描述wdnmd,这么多数据返回,然后我们亲爱的后端和我说,我要是服务器升级,你这里请求一万条,我也给你返回一万条?

然后分析了一下,好像是因为 他一旦服务器断重连的时候,就会调用initWebSocket这个函数,然后就会一直 new WebSocket 这个东西发到服务器,然后当服务器连上的时候,一次性全给你返回来了,你发多少,他就会返回多少

也就是相当于以下代码

for(var i = 0 ; i<10 ; i++){
new object
}

相当于创建了10个对象,然后不停的发送给服务器,然后服务器就会一条一条给你返回

(很奇怪,自己用node搭的时候就不会出现这种问题,那既然需求出现了,就要改)

然后偶然间看到了这位兄弟写的博客,但是不符合我的要求,所以就照虎画猫改了改,代码如下

这位兄弟的博客地址如下:

点击跳转连接地址,或者复制以下地址
https://blog.csdn.net/woflyoycm/article/details/95543776

以下是我修改后的代码

data(
	return{
            websocket: null,
            isConnect : false,
            rec: null,
	}
)
            
created() {
        var that = this;

        //页面刚进入时开启长连接
        this.createWebSocket()

    },
    destroyed: function() {
        //页面销毁时关闭长连接
        this.websocketclose();
    },
    methods: {
        createWebSocket(){
            try {
                //尝试连接
                const wsuri = this.BASE_URL_WS; //ws地址
                console.log(this.BASE_URL_WS)
                this.websocket = new WebSocket(wsuri);
                this.initWebSocket();
            } catch (e) {
                console.log('尝试创建连接失败');
                //如果无法连接上webSocket 那么重新连接!可能会因为服务器重新部署,或者短暂断网等导致无法创建连接
                this.reConnect();
            }
        },
        initWebSocket() {
            // 初始化weosocket
            this.isConnect = true;
            this.websocket.onopen = this.websocketonopen;      
            this.websocket.onerror = this.websocketonerror;     
            this.websocket.onmessage = this.websocketonmessage; 
            this.websocket.onclose = this.websocketclose;
        },
        reConnect(){
            //重连函数
            var that = this
            if(this.isConnect) return;
            this.rec&&clearTimeout(this.rec);
            // 延迟5秒重连  避免过多次过频繁请求重连
            this.rec=setTimeout(function(){
                that.createWebSocket();
            },5000);
        },
            //连接成功提示字样
        websocketonopen() {
            console.log("WebSocket连接成功");
        },
            //连接错误
        websocketonerror(e) {
            this.isConnect=false;
            //调用重连函数
            this.reConnect();
            console.log("WebSocket连接发生错误");
        },
            //数据接收
        websocketonmessage(e) {
            console.log(e);
            if(e !== undefined){

                console.log(e);
                this.msg = e.data;
                var json = JSON.parse(e.data);
                console.log(json);
                    this.setCache('carOut',json )
            }
        },
            //服务关闭
        websocketclose(e) {
            // this.initWebSocket();
            this.isConnect=false;
            //重连
            this.reConnect();
            console.log("connection closed (" + e.code + ")");
        },
    }

在这里插入图片描述这样就行了

就是有了个判断机制,然后有个isConnect 这个是否重连的变量,然后如果websocket初始化了之后,就会调用这个初始化的,而不会去新建别的

Logo

前往低代码交流专区

更多推荐