vue实现WebSoket及时通讯

话不多少上代码
utils里新建websoket.js

import Vue from 'vue'
import { Message } from 'element-ui'
let v = new Vue()
v.$message = Message;
var webSocket = null;
var isConnect = false; //连接状态
var globalCallback = function(e){ console.log(e) };//定义外部接收数据的回调函数
var reConnectNum = 0;//重连次数
let userId = sessionStorage.getItem("userId")
var websocketUrl =  `ws://192.168.220.111:9080/websocket/${userId}`;
 
//心跳设置
var heartCheck = {
    heart:"heart",//心跳包
    timeout: 45 * 1000, //每段时间发送一次心跳包 这里设置为60s
    heartbeat: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)
    start: function () {
        this.heartbeat = setInterval(()=>{
            if (isConnect){
                webSocketSend(this.heart);
            }else{
                this.clear();
            }
        }, this.timeout);
    },
    reset: function () {
        clearInterval(this.heartbeat);
        this.start();
    },
    clear:function(){
        clearInterval(this.heartbeat);
    }
}

//初始化websocket
function initWebSocket(callback) {
    //此callback为在其他地方调用时定义的接收socket数据的函数
    if(callback){
        if(typeof callback == 'function'){
            globalCallback = callback     
        }else{
            throw new Error("callback is not a function")
        }
    }
    if ("WebSocket" in window) {
        webSocket = new WebSocket(websocketUrl);//创建socket对象
    } else {
        Message({
            message: '该浏览器不支持websocket!',
            type: 'warning'
        });
        return
    }
    //打开
    webSocket.onopen = function() {
        webSocketOpen();
    };
    //收信
    webSocket.onmessage = function(e) {
        webSocketOnMessage(e);
    };
    //关闭
    webSocket.onclose = function(e) {
        webSocketOnClose(e);
    };
    //连接发生错误的回调方法
    webSocket.onerror = function(e) {
        webSocketonError(e);
    };
}
//连接socket建立时触发
function webSocketOpen() {
    console.log("WebSocket连接成功");
    //首次握手
    webSocketSend(heartCheck.heart);
    isConnect = true;
    heartCheck.start();
    reConnectNum = 0;
}
 
//客户端接收服务端数据时触发,e为接受的数据对象
function webSocketOnMessage(e) {
    console.log("websocket信息:");
    console.log(e.data)
    if(e.data == "stopUser") {
        Message({
            message: '你已被上级管理员停用即将跳转登录页',
            type: 'warning'
        });
        setTimeout(() => {
            window.location.href = vueConfig.jqUrl + "vue/web/login"
        }, 3000);
    }
    const data = JSON.parse(e.data);//根据自己的需要对接收到的数据进行格式化
    globalCallback(data);//将data传给在外定义的接收数据的函数,至关重要。
}
 
//socket关闭时触发
function webSocketOnClose(e){
    heartCheck.clear();
    isConnect = false; //断开后修改标识
    console.log(e)
    console.log('webSocket已经关闭 (code:' + e.code + ')')
    //被动断开,重新连接
    if(e.code == 1006){
        if(reConnectNum < 3){
            initWebSocket();
            ++reConnectNum;
        }else{
            v.$message({
                message: 'websocket连接不上,请刷新页面或联系开发人员!',
                type: 'warning'
            });
        }
    }
}
 
//连接发生错误的回调方法
function webSocketonError(e){
    heartCheck.clear();
    isConnect = false; //断开后修改标识
    console.log("WebSocket连接发生错误:");
    console.log(e);
}
 
 
//发送数据
function webSocketSend(data) {
    webSocket.send(JSON.stringify(data));//在这里根据自己的需要转换数据格式
}
//在其他需要socket地方主动关闭socket
function closeWebSocket(e) {
    webSocket.close();
    heartCheck.clear();
    isConnect = false;
    reConnectNum = 0;
}
//在其他需要socket地方接受数据
function getSock(callback) {
    globalCallback = callback
}
//在其他需要socket地方调用的函数,用来发送数据及接受数据
function sendSock(agentData) {
    //下面的判断主要是考虑到socket连接可能中断或者其他的因素,可以重新发送此条消息。
    switch (webSocket.readyState) {
        //CONNECTING:值为0,表示正在连接。
        case webSocket.CONNECTING:
            setTimeout(function() {
                sendSock(agentData, callback);
            }, 1000);
        break;
        //OPEN:值为1,表示连接成功,可以通信了。
        case webSocket.OPEN:
            webSocketSend(agentData);
        break;
        //CLOSING:值为2,表示连接正在关闭。
        case webSocket.CLOSING:
            setTimeout(function() {
                sendSock(agentData, callback);
            }, 1000);
        break;
        //CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
        case webSocket.CLOSED:
        // do something
        break;
        default:
        // this never happens
        break;
    }
}
 
export default {
  initWebSocket,
  closeWebSocket,
  sendSock,
  getSock
};
  1. main.js引入挂载原型
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import axios from "./utils/api/index";
import utils from "./utils";
import socketApi from "./utils/websocket";
Vue.prototype.$socketApi = socketApi;//websocket挂在原型上

3.使用

 beforeDestroy() {//销毁的生命周期
	   this.$socketApi.closeWebSocket();
  },
  mounted() {//挂载的生命周期
    this.$socketApi.initWebSocket(this.getsocketResult);
  },
 methods: {
    // socket信息返回接受函数
	   getsocketResult(data) {
	     console.log(data);
	   },
	   //发送socket信息
	   websocketSend(data) {
	     this.$socketApi.sendSock(data);
	   },
 },

注意的点

vue3 Content Security Policy: 升级不安全的请求,会有强制跳转https的问题
ws会替换成wss的请求会一直连接不上
在这里插入图片描述
在这里插入图片描述
public下的index.html 里meat头要去掉

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

最后你就大功告成
在这里插入图片描述

Logo

前往低代码交流专区

更多推荐