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

2023-05-16

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

1 初始化连接

/**
 * @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次之后会提示用户手动刷新

/**
 * @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); // 发送消息给后端请求数据

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3使用websocket简易封装,包含错误重连机制 的相关文章

随机推荐