acdr-ui/dist/dev/mp-weixin/modules/mall/sheep/hooks/useWebSocket.js
2024-10-01 09:15:35 +08:00

133 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
const common_vendor = require("../../../../common/vendor.js");
const modules_mall_sheep_config_index = require("../config/index.js");
const modules_mall_sheep_util_index = require("../util/index.js");
function useWebSocket(opt) {
const getAccessToken = () => {
return common_vendor.index.getStorageSync("token");
};
const options = common_vendor.reactive({
url: (modules_mall_sheep_config_index.baseUrl + modules_mall_sheep_config_index.websocketPath).replace("http", "ws") + "?token=" + getAccessToken(),
// ws 地址
isReconnecting: false,
// 正在重新连接
reconnectInterval: 3e3,
// 重连间隔,单位毫秒
heartBeatInterval: 5e3,
// 心跳间隔,单位毫秒
pingTimeoutDuration: 1e3,
// 超过这个时间后端没有返回pong则判定后端断线了。
heartBeatTimer: null,
// 心跳计时器
destroy: false,
// 是否销毁
pingTimeout: null,
// 心跳检测定时器
reconnectTimeout: null,
// 重连定时器ID的属性
onConnected: () => {
},
// 连接成功时触发
onClosed: () => {
},
// 连接关闭时触发
onMessage: (data) => {
}
// 收到消息
});
const SocketTask = common_vendor.ref(null);
const initEventListeners = () => {
SocketTask.value.onOpen(() => {
console.log("WebSocket 连接成功");
options.onConnected();
startHeartBeat();
});
SocketTask.value.onMessage((res) => {
try {
if (res.data === "pong") {
resetPingTimeout();
} else {
options.onMessage(JSON.parse(res.data));
}
} catch (error) {
console.error(error);
}
});
SocketTask.value.onClose((event) => {
if (options.destroy) {
options.onClosed();
} else {
stopHeartBeat();
reconnect();
}
});
};
const sendMessage = (message) => {
if (SocketTask.value && !options.destroy) {
SocketTask.value.send({ data: message });
}
};
const startHeartBeat = () => {
options.heartBeatTimer = setInterval(() => {
sendMessage("ping");
options.pingTimeout = setTimeout(() => {
reconnect();
}, options.pingTimeoutDuration);
}, options.heartBeatInterval);
};
const stopHeartBeat = () => {
clearInterval(options.heartBeatTimer);
resetPingTimeout();
};
const reconnect = () => {
if (options.destroy || !SocketTask.value) {
return;
}
options.isReconnecting = true;
if (options.reconnectTimeout) {
clearTimeout(options.reconnectTimeout);
}
options.reconnectTimeout = setTimeout(() => {
if (!options.destroy) {
options.isReconnecting = false;
initSocket();
}
}, options.reconnectInterval);
};
const resetPingTimeout = () => {
if (options.pingTimeout) {
clearTimeout(options.pingTimeout);
options.pingTimeout = null;
}
};
const close = () => {
options.destroy = true;
stopHeartBeat();
if (options.reconnectTimeout) {
clearTimeout(options.reconnectTimeout);
}
if (SocketTask.value) {
SocketTask.value.close();
SocketTask.value = null;
}
};
const initSocket = () => {
options.destroy = false;
modules_mall_sheep_util_index.copyValueToTarget(options, opt);
SocketTask.value = common_vendor.index.connectSocket({
url: options.url,
complete: () => {
},
success: () => {
}
});
initEventListeners();
};
initSocket();
common_vendor.onBeforeUnmount(() => {
close();
});
return { options };
}
exports.useWebSocket = useWebSocket;