首页IT科技vue/cli-service(vue项目使用websocket连接问题及解决)

vue/cli-service(vue项目使用websocket连接问题及解决)

时间2025-06-20 15:54:14分类IT科技浏览6039
导读:vue使用websocket连接 前景...

vue使用websocket连接

前景

公司做一个包含websocket的项目             ,我用的是vue做的                     ,开始只有一个组件的要求demo        ,就将websocket的配置直接放在组件方法中          ,组件挂载时直接初始化ws                    ,但是后续组件增加            ,开始出现多个websocket链接的情况       ,是不允许的               。

刚开始的做法是将websocket的方法配置等封装为一个js文件给各个组件调用                   ,当离开组件页面进入新页面时会断连旧的ws新建一个ws                ,以为做到了独立    ,但是实际上确实多次的断连链接                   ,十分不便                     。

思考了挺久找到了解决方法                   ,在此记录加深记忆

解决过程

要求整个vue项目使用一个ws链接,在各组件都要求可以接受发送消息

首先想到的就是在app.vue下创建我是链接                ,然后给各个小的组件使用ws                      ,做到统一    ,很简单的解决思路             ,我是这么做的

前期已经将ws封装成一个wsconnect.js文件了                     ,那么是否可以将wsconnect注册为全局的方法呢        ,试了一下果真可行          ,只需要在main.js中配置:

import wsConnect from "@/assets/js/wsConnect"; Vue.prototype.$ws = wsConnect   new Vue({   render: h => h(App),   router,   axios,   store }).$mount(#app)

说明一下                    ,在wsconnect.js文件中我封装了方法            ,但是把ws对象放在了vuex的state中       ,相关配置如下:

wsconnect.js:

import axios from "axios"; import store from "@/store";   //websocket   function initWebpack(){     var url = store.state.url     var wsurl =     axios.get(`${url}/bcall/url`)  //这是我在从后端拿ws链接的地址         .then((res) =>  {             console.log(res.data.data)             wsurl = res.data.data             store.state.ws = new WebSocket(wsurl);             store.state.ws.onopen = onopen;             store.state.ws.onmessage = onmessage;             store.state.ws.onclose = onclose;             store.state.ws.onerror = onerror;           }).catch((err)=> {         console.log(err)     })   } function onopen() {     console.log("连接websocket");     var params = {"reqtype":"Query","action":"allexts"}     store.state.ws.send(params)     start(); } function reconnect() {//重新连接     var that = store.state;     if(that.lockReconnect) {         return;     }     that.lockReconnect = true;     //没连接上会一直重连                   ,设置延迟避免请求过多     that.timeoutnum && clearTimeout(that.timeoutnum);     that.timeoutnum = setTimeout(function () {         //新连接         initWebpack();         that.lockReconnect = false;         that.isFirstGet = true     },5000); } function reset(){//重置心跳     var that = store.state;     //清除时间     clearTimeout(that.timeoutObj);     clearTimeout(that.serverTimeoutObj);     //重启心跳     start(); } function start(){ //开启心跳     console.log(开启心跳);     var self = store.state;     self.timeoutObj && clearTimeout(self.timeoutObj);     self.serverTimeoutObj && clearTimeout(self.serverTimeoutObj);     self.timeoutObj = setTimeout(function(){         //这里发送一个心跳                ,后端收到后    ,返回一个心跳消息                   ,         if (self.ws.readyState === 1) {//如果连接正常                          self.ws.send(heartbeat); //心跳包格式需要自己确定           }else{//否则重连             reconnect();         }         self.serverTimeoutObj = setTimeout(function() {             //超时关闭             self.ws.close();             reconnect()         }, self.timeout);     }, self.timeout) } function onmessage(e) {     console.log(接收数据,e)     //处理数据的地方     reset(); } function onclose(e) {     console.log(websocket 断开: ,e);   } function onerror(e) {     console.log("出现错误");     //重连     reconnect(); }     export default {     initWebpack,     onmessage,     onclose,     onopen,     onerror }

store.state:

state: {         permissions: false,         url: ,         //ws参数         path: ,         ws: null,//建立的连接         lockReconnect: false,//是否真正建立连接         timeout: 58*1000,//58秒一次心跳         timeoutObj: null,//心跳心跳倒计时         serverTimeoutObj: null,//心跳倒计时         timeoutnum: null,//断开 重连倒计时       },

配置之后我在app.vue挂载之后直接初始化ws链接:

mounted() {     this.$ws.initWebpack()   }

发现是成功的                   ,已经将ws链接上了,接着就是在各个组件测试一下发送数据的功能:

this.$store.state.ws.send(msg)

神奇的发现                ,也成功了!

之所以这么简单                      ,前期的封装也是占功劳的嘛    ,至此我的vue只需要一个ws链接就可以供整个项目使用             ,虽然不知道别人的做法是怎么样                     ,如果有更好的方法也希望大家讲解下

vue2全局使用websocket记录

1             、考虑到登录之后要始终连接服务器接收消息        ,所以把websocket实例对象作为模块抛出          ,在main.js中引入                    ,使全局都可以获得ws并且使用相关方法      。

2                     、由于刷新页面时            ,ws会自动断开连接       ,所以在App.vue组件挂载时再次连接服务器           。

新建ws模块文件

该文件位置任意                   ,引入的时候注意路径即可

export default {     ws: {},     setWs: function(newWs) {         this.ws = newWs     },     start(){// 发送心跳         clearInterval(this.timeoutObj)         this.timeoutObj = setInterval(() => {             if (this.ws && this.ws.readyState == 1) {                 console.log(发送心跳)                 this.ws.send(JSON.stringify({                     //后端需要接收的数据                 }));             }         }, 10 *1000)//十秒发一次     },     localSocket(userId) {//连接ws                ,根据连接服务器是否需要参数设置该方法是否需要接收参数         if ("WebSocket" in window) {             // console.log("您的浏览器支持 WebSocket!");             // location.host             this.ws = new WebSocket(这里要填连接服务器的地址);             this.setWs(this.ws);             this.ws.onopen = ()=>{                 console.log(websocket连接成功);                 //连接上之后要发心跳包                 this.start()             };             this.ws.onclose = function () {                 // 关闭 websocket                 console.log("连接已关闭...");                 //断线重新连接                 setTimeout(() => {                     this.localSocket(userId);                 }, 2000);             };         } else {             // 浏览器不支持 WebSocket             console.log("您的浏览器不支持 WebSocket!");             this.openNotificationWithIcon(error, 浏览器, 您的浏览器不支持显示消息请更换, 1,1)         }     }, } 

在main.js中引用ws模块文件

import global from ./ws.js Vue.prototype.global = global

App.vue挂载时再次连接服务器并且接收消息

mounted(){       this.global.localSocket(userId)       //连上之后要接收服务器发来的消息       this.global.ws.onmessage = (msg)=>{           console.log(JSON.parse(msg.data))        } }

通过以上方法    ,任何组件都可以通过this.global.ws获得websocket实例对象并且使用相关方法                   ,可能会有些问题                   ,但是我别的问题太多了,这个先放一下吧                      。

以上为个人经验                ,希望能给大家一个参考                      ,也希望大家多多支持本站         。

声明:本站所有文章    ,如无特殊说明或标注             ,均为本站原创发布       。任何个人或组织                     ,在未征得本站同意时        ,禁止复制        、盗用          、采集                    、发布本站内容到任何网站            、书籍等各类媒体平台                       。如若本站内容侵犯了原著者的合法权益          ,可联系我们进行处理            。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
teradata top(Teradata支持云计算吗)