vue项目使用websocket连接问题及解决

目录
  • vue使用websocket连接
    • 前景
    • 解决过程
  • vue2全局使用websocket记录
    • 新建ws模块文件
    • 在main.js中引用ws模块文件
    • App.vue挂载时再次连接服务器并且接收消息

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实例对象并且使用相关方法,可能会有些问题,但是我别的问题太多了,这个先放一下吧。

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

(0)

相关推荐

  • vue使用websocket概念及示例

    目录 概念部分: 使用示例 概念部分: 1,WebSocket 是 HTML5 提供的 TCP 连接上进行全双工通讯的协议.一次握手之后,服务器和客户端可以互相主动通信,双向传输数据. 2,浏览器想服务器发送请求,建立连接之后,可通过send()方法想服务器发送数据,并通过message事件接受服务器返回的数据. 使用示例 <script> export default { mounted() { this.connectWebsocket(); }, methods: { connectWe

  • vue3+ts+Vuex中使用websocket协议方式

    目录 vue3+ts+Vuex使用websocket协议 在stroe中 vue3中 vue封装websocket 封装的socket.js文件内容 使用方法 vue3+ts+Vuex使用websocket协议 本文作者使用的是ts+vue3的setup语法糖,大家注意使用的vue版本! 在stroe中 import { createStore } from 'vuex' import { stateInt } from '../interface/storeInterface' const s

  • Vue websocket封装实现方法详解

    目录 1.封装的ws.js文件 2.使用方法 1.封装的ws.js文件 let global_callback = null let socket = '' // 存储 WebSocket 连接. let timeoutObj = null // 心跳定时器 let serverTimoutObj = null // 服务超时定时关闭 let lockReconnect = false // 是否真正建立了连接 let timeoutnum = null // 重新连接的定时器, 没连接上会一直

  • vue3.0中使用websocket,封装到公共方法的实现

    目录 使用websocket,封装到公共方法 vue中封装websocket问题 1.在untils文件夹下新建socket_service.js 2.在main.js里引用 2.在组件里调用$socket 使用websocket,封装到公共方法 首先创建一个socket.ts文件封装公共方法 /* * @Descripttion: 封装socket方法 * @version: * @Date: 2021-08-06 11:14:39 * @LastEditTime: 2021-10-26 14

  • Vue项目使用Websocket大文件FileReader()切片上传实例

    目录 使用技术 upfile.js文件 新增需求:对上传文件流进行加密,并传给后端做验证 还是在upfile.js文件(也可以单独放一个文件) 大文件上传,本地1.3G文件不到一分钟上传完毕 使用技术 Vue框架 WebSocket双向传输 FileReader读取文件 封装的WebSocket请求文件上传方法,目前只支持单文件上传,有研究出来多文件上传,记得评论哦 upfile.js文件 //file.slice(起始字节,终止字节)与FileReader实现文件切片读取 function P

  • vue项目使用websocket连接问题及解决

    目录 vue使用websocket连接 前景 解决过程 vue2全局使用websocket记录 新建ws模块文件 在main.js中引用ws模块文件 App.vue挂载时再次连接服务器并且接收消息 vue使用websocket连接 前景 公司做一个包含websocket的项目,我用的是vue做的,开始只有一个组件的要求demo,就将websocket的配置直接放在组件方法中,组件挂载时直接初始化ws,但是后续组件增加,开始出现多个websocket链接的情况,是不允许的. 刚开始的做法是将web

  • Vue项目通过node连接MySQL数据库并实现增删改查操作的过程详解

    目录 Vue项目通过node连接MySQL数据库 1.创建Vue项目 2.下载安装需要的插件 3.在项目中创建server文件夹,用于搭建本地服务器 4.Vue项目访问接口获取数据 数据表的增删改查操作 1.服务器配置 2.前端配置 页面样式 总结 Vue项目通过node连接MySQL数据库 1.创建Vue项目 vue create 项目名 Vue项目创建的详细步骤,有需要的可移步这里 2.下载安装需要的插件 下载express npm install express 下载cors,用于处理接口

  • vue项目热更新的坑及解决

    目录 vue项目热更新坑 vue项目热更新慢 查找热更新慢是哪里慢—分析原因 解决办法 vue项目热更新坑 今天在使用vue-cli构造的vue项目时,遇到一个坑. setInterval(() => { console.log('This is one.') }, 10000) 运行后如下: 这时我们修改其中的代码,不刷新网页: setInterval(() => { console.log('This is two.') }, 1000) 结果如下,发现之前的计时函数以久存在,热更新 !=

  • vue项目无法删除的问题及解决

    目录 vue项目无法删除 vue新增与删除问题 vue项目无法删除 问题 今天删除本地的vue项目,一直提示“操作无法完成,因为其中的文件夹或文件已在另一个程序组打开,请关闭该文件夹或文件,然后重试”. 但是相关的软件我都关闭了,还是不行.如图 解决 我们ctrl+alt+delete打开任务管理器,点击详细信息,找到node.exe 右击选择结束任务,然后点击结束进程,然后就可以成功删除项目了. vue新增与删除问题 <template>   <div>     <ul v

  • Vue项目报错:parseComponent问题及解决

    目录 Vue项目报错:parseComponent 报错内容 解决步骤 Vue常见错误及解决办法 1.在配置路由并引入组件后 2.在组件中的标签和样式中图片路径出错时 3.在组件中标签没有闭合 4.在使用less定义变量是报错 本地开发环境请求服务器接口跨域的问题 Vue项目报错:parseComponent 报错内容 ERROR  Failed to compile with 1 error                                                    

  • vue项目打包后打开页面空白解决办法

    网上很多说自己的VUE项目通过Webpack打包生成的list文件,放到HBulider打包后,通过手机打开一片空白.这个主要原因是路径的问题. 1.记得改一下config下面的index.js中bulid模块导出的路径.因为index.html里边的内容都是通过script标签引入的,而你的路径不对,打开肯定是空白的.先看一下默认的路径. module.exports = { build: { env: require('./prod.env'), index: path.resolve(__

  • mui-player自定义底部导航在vue项目中显示不出来的解决

    目录 mui-player自定义底部导航在vue项目中显示不出 效果图 总结 mui-player自定义底部导航在vue项目中显示不出 看了作者的源码和案例等,先上代码: <template> <div class="content-box"> <div class="container"> <div>视频插件 mui-player</div> <div id="mui-player&quo

  • vue项目打包后怎样优雅的解决跨域

    前言 在使用vue.js开发前端项目时,再结合webpack搞起各种依赖.各种插件进行开发,无疑给前端开发带来了很多便捷,就在解决跨域这个问题上,相信众多用vue.js的前端同僚们同我一样尝到了甜头,开发环境全靠proxyTable一通配置简直不要太酸爽.还不明所以然的新手们可能还没搞清我说的是什么,就是下面这几行配置: proxyTable: { '/api': { target: 'http://113.113.113.113:5000', //假的接口地址哈 changeOrigin: t

  • 解决VUE项目localhost端口服务器拒绝连接,只能用127.0.0.1的问题

    Vue项目不能使用localhost:8xx0进入项目,但是将localhost替换为127.0.0.1却可以进入. 解决办法: 进入文件 C:\Windows\System32\drivers\etc\hosts 用记事本打开 hosts 文件进行编辑,看看文件里是否有 127.0.0.1 localhost localhost 127.0.0.1 如果没有的话就加上,具体加入位置如下 # 127.0.0.1 localhost # ::1 localhost //加上的代码 127.0.0.

随机推荐