vue3使用websocket简易封装,包含错误重连机制

这篇具有很好参考价值的文章主要介绍了vue3使用websocket简易封装,包含错误重连机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

websocket实现的全双工通信,真真太香了,以下是笔者在使用时,自己封装的一个简易js工具。若需要源码,请移步这里

1 初始化连接

let socket = null; // 连接对象
let linkFailCount = 0; // 连接次数,目前连接三次
let relinkLoading = null;// 重连全屏loading

/**
 * @description: 初始化websocket
 * @param {*} linkUrl url的地址
 * @return {WebSocket} WebSocket对象
 * @Author: liuxin
 */
function initWebSocket(linkUrl = "") {
    // 正在连接或连接成功
    if (socket && (socket.readyState < 2)) {
        return socket;
    }

    // 如果地址由上层传递过来,则使用传递的地址
    if (linkUrl) {
        Window.apiConfig[process.env.NODE_ENV].wsUrl = linkUrl;
    }
    const url = Window.apiConfig[process.env.NODE_ENV].wsUrl;
    socket = new WebSocket(url) // 创建对象
    socket.onerror = webSocketOnError; // 连接错误处理
    socket.onclose = closeWebsocket; // 连接关闭处理
    socket.onopen = openWebsocket; // 连接打开处理
    return socket;
}

2 连接打开回调

/**
 * @description: 打开websocket回调函数处理
 * @return {*}
 * @Author: liuxin
 */
function openWebsocket() {
    console.log("WebSocket连接打开...");
    linkFailCount = 0;// 打开连接,连接次数改为0
    // 加载动画如果开启,则关闭
    if (relinkLoading) {
        relinkLoading.close();
    }
}

3 连接关闭回调

/**
 * @description: 关闭websocket回调函数处理
 * @return {*}
 * @Author: liuxin
 */
function closeWebsocket() {
    // 连接关闭时,立刻开启重连机制
    if (linkFailCount < 3 && socket && (socket.readyState >= 2)) {
        // 开启重连加载动画
        relinkLoading = ElLoading.service({
            lock: true,
            text: `连接关闭了,正在重连,请稍等...`,
        })
        initWebSocket();
    }
}

4 连接错误处理

笔者这里会重连3次,重连的过程给与用户提示,3次之后会提示用户手动刷新

vue3使用websocket简易封装,包含错误重连机制

vue3使用websocket简易封装,包含错误重连机制

/**
 * @description: 连接错误回调函数处理
 * @param {*} e 错误对象
 * @Author: liuxin
 */
function webSocketOnError(e) {
    linkFailCount++;// 连接失败的次数
    if (relinkLoading) {
        relinkLoading.close(); // 关闭重连加载动画
    }
    //连接三次
    if (linkFailCount < 3) {
        initWebSocket();
        // 开启重连加载动画
        relinkLoading = ElLoading.service({
            lock: true,
            text: `第${linkFailCount}次连接失败,正在尝试第${linkFailCount + 1}次重新连接,请稍等...`,
        })
    } else {
        ElMessageBox.confirm(
            '连接失败,是否尝试刷新?',
            '警告',
            {
                confirmButtonText: '刷新',
                cancelButtonText: '取消',
                type: 'warning',
                "close-on-click-modal": false
            }
        )
            .then((e) => {
                if (e == "confirm") {
                    location.reload();
                }
            })
    }
}

 5 数据处理

这里与后端约定的数据返回,加上type作为接口判断依据,因此这里不一定通用。

返回数据接口:{type:"xxx",data:{}}

/**
 * @description: 处理websocket返回的数据
 * @param {*} res 后端返回的数据
 * @return {Object<JSON>} 
 * @Author: liuxin
 */
function webscoketDealData(res, type) {
    const data = JSON.parse(res.data);
    if (data.code !== 200) {
        ElMessage.error("服务器错误" + data.message || "");
        return { type: "error" };
    }
    const returnData = { type: data.type, data: data.data };
    // 打印日志在前端
    // if (type && type == data.type) {
    // console.log('消息回来了-----', returnData);
    // }
    return returnData;
}

6 使用示例

      const socket = initWebSocket(state.webSocketUrl); // 连接websocket

      if (socket) {
        // 这个写法会导致多次进入监听事件
        socket.addEventListener("message", (scev) => {
          console.log(scev.data);
          state.returnData.push(scev.data);
        });

        /* 监听socket关闭 */
        socket.addEventListener("close", () => {
          state.returnData.push("连接关闭");
        });
      }

      sendMessage("escalator_data_detail", state.params); // 发送消息给后端请求数据


以下是在上述的基础上,为整改页面监听message多次进入的问题,进行的一个优化处理

7 优化消息处理

7.1 消息存储在store仓库

import store from "@/store";

/**
 * @description: 初始化websocket
 * @param {*} link url后更上的地址
 * @return {WebSocket} WebSocket对象
 * @Author: liuxin
 */
function initWebSocket() {
    // 正在连接或连接成功
    if (socket && (socket.readyState < 2)) {
        return socket;
    }
    const url = Window.apiConfig[process.env.NODE_ENV].wsUrl;
    socket = new WebSocket(url)//这里面的this都指向vue 
    socket.onerror = webSocketOnError;
    socket.onclose = closeWebsocket;
    socket.onopen = openWebsocket;
    socket.onmessage = (res) => {
        // console.log("消息回来了-----", res.data);
        const data = JSON.parse(res.data);
        if (data.code !== 200) {
            ElMessage.error("服务器错误:" + data.message || "");
        }
        store.commit("commitSocketData", data); // 将消息存入仓库中,而后使用则在仓库取,不再监听message事件
    };
    return socket;
}

7.2 引入仓库存储

import { createStore } from 'vuex'
export default createStore({
  state: {
    // 用于存储websocket返回的数据 {后端的给定的type:后端的数据}
    socketData: {
    },
  },
  getters: {
    /**
     * @description: 获取webscoket返回的数据
     * @return {*}
     * @Author: liuxin
     */
    getSocketDataByType: (state) => (type) => {
      if (Object.hasOwnProperty.call(state, type)) {
        return state[type].data;
      }
    }
  },
  mutations: {
    /**
     * @description: 
     * @param {*} state state对象
     * @param {*} commitData {type:"后端的api类型",data:"后端的数据"}
     * @return {*}
     * @Author: liuxin
     */
    commitSocketData(state, commitData) {
      // 如果没有数据,则直接返回
      if (!commitData || !commitData.type) {
        return;
      }
      state.socketData[commitData.type] = {}; // 初始化一个对象
      state.socketData[commitData.type].data = commitData.data; // 添加数据存储
      state.socketData[commitData.type].timelyFlag = Date.now(); // 添加时间戳,保证每次后端的数据都能更新成功
    },
  },
})

7.3  使用说明

直接引入store仓库,监听仓库数据变化文章来源地址https://www.toymoban.com/news/detail-503967.html

import { useStore } from "vuex"; // 引入vuex

const store = useStore(); // 创建store对象


        /**
     * @description: 监听vuex获取的数据变化,用于展示在前端
     * @Author: liuxin
     */
    watch(
      () => store.state.socketData["escalator_data_detail"], // 这里escalator_data_detail是后端返回的type
      (newData) => {
        dealData(newData.data); // 处理数据
      }
    );

7.4编写一个公共发送消息方法

/**
 * @description: 发送websocket数据给后端
 * @param {String} method 方法
 * @param {JSON} params 参数
 * @return {Object<JSON>} 
 * @Author: liuxin
 */
function sendMessage(method, params) {
    const _data = {
        api: method,
        data: {
            ...params,
        }
    };

    if (socket && socket.readyState == 1) {
        // console.log("sendMessage----------", _data);
        socket.send(JSON.stringify(_data))
    } else {
        // 监听socket打开
        socket.addEventListener("open", () => {
            // console.log("sendMessage -----open-----", _data);
            socket.send(JSON.stringify(_data))
        });
    }
}

到了这里,关于vue3使用websocket简易封装,包含错误重连机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue3的vue-chart组件封装(包含数据刷新按需使用)

    v-chart封装数据更新效果 初始数据展示:  刷新数据展示: v-charts Description https://v-charts.js.org/#/ npm i v-charts echarts -S / yarn add v-charts echarts -S 先别急着直接定义option对象,可以参考官网这个方法: Documentation - Apache ECharts 也就是通过实例,调用setOption这个方法,可以不通过传递

    2024年02月02日
    浏览(45)
  • uniapp websocket 封装断线重连

     1.新建一个工具类js文件 2. 把我封装的代码复制进去 我是用uniapp 的api封装的 在外面也可以直接用uniapp的api操作 只有在开始调用连接需要用封装的方法调用 在需要使用封装的方法的页面 引入js     import {         websocetObj     } from \\\"@/API/websocket.js\\\"  完善重连 在app.vue的

    2024年02月11日
    浏览(38)
  • websocket前端封装代码,心跳机制断线重连

    websocket是一种全双工通信长链接,大多用来实现及时通讯,数据实时性要求较为高的地方,在websoket未出现的时候前端使用的setInterval轮训进行数据更新的,在那些对于数据实时性要求不高地方我们仍可以使用 轮训。 (1)建立在 TCP 协议之上,服务器端的实现比较容易。 (

    2024年02月11日
    浏览(54)
  • Flutter:WebSocket封装-实现心跳、重连机制

    前言Permalink Flutter简介 Flutter 是 Google推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart语言开发 App,一套代码同时运行在 iOS 和 Android平台。 Flutter提供了丰富的组件、接口,开发者可以很快地为 Flutter添加 native扩展。同时 Flutter还使用 Nat

    2024年02月10日
    浏览(53)
  • 基于Vue3封装一个好用的Websocket

    在Vue3中使用Websocket可以让我们轻松地实现实时数据传输。为了方便使用,我们可以封装一个好用的Websocket类。 首先我们需要安装 ws 库来处理Websocket连接,使用以下命令进行安装: 我们可以新建一个 websocket.js 文件,在其中定义一个 Websocket 类,代码如下: 以上代码中,我们

    2024年02月04日
    浏览(92)
  • Vue3封装全局WebSocket;全局可监听、可发送、心跳处理等;

    操作如下 可以在多个页面多个组件中进行监听/发送 代码简介 方便; 首先安装 tools-javascript 以及 tools-vue3 根据你的业务需求初始化 ws 在你的任何文件中直接调用即可 附加篇(也可不读 直接看文档 )

    2024年02月11日
    浏览(42)
  • vue3 codemirror关于 sql 和 json格式化的使用以及深入了解codemirror 使用json格式化提示错误的关键代码。包含了json格式化没有效果和json格式化提示错误

    后端返回一个json字符串,里面有value1、value2指定字段渲染sql语句,其他渲染json语句。 jsonlint 和 jsonlint-mod 的区别 简单理解:jsonlint校验json格式化是否有效,jsonlint-mod用来格式化后同时校验json格式化是否有效。 (1)JSONLint是一种可以验证JSON格式是否有效的工具。 它可以检查

    2024年04月28日
    浏览(77)
  • vue封装和使用websocket

    最近做了一个数据大屏的项目,使用了websocket来实现数据实时更新的需求,简单记录分享一下。 1、WebSocket协议是基于TCP的一种新的网络协议,允许服务端主动向客户端推送数据,实现全双工通信。 2、在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可

    2024年02月06日
    浏览(38)
  • Vue+Nodejs 使用WebSocket创建一个简易聊天室

    使用vue编写前端页面,nodejs处理服务端消息,WebSocket进行实时通信 1.客户端 2. 服务端 使用的是nodejs

    2024年02月16日
    浏览(45)
  • Vue3 报 WebSocket connection to ‘ws://x.x.x.x:8080/ws‘ failed 的错误

    问题:控制台每过几秒就报WebSocket的错误,但是页面显示正常。 原因:WebSocket是一种双向通信的协议,它在尝试建立到 \\\'ws://x.x.x.x:8080/ws\\\' 的通信失败。原因可能是服务器 \\\'x.x.x.x\\\' 不可用,或WebSocket服务未正确配置。因此,我们去配置一下通信问题。 解决: 整体代码: 重点:修

    2024年02月04日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包