socketCommon.js websock的通用js
let websock = null;
let global_callback = null;
let global_erroCallback = null;
let global_timeoutCallback = null;
let retries = 0; // 重连次数
let maxRetries = 5; // 最多重连次数
const heartbeatInterval = 1000 * 5; // 心跳时的间间隔
const reconnectInterval = 1000 * 3; // 重连的时间间隔
let heartbeatTimer = null;
let reconnectTimer = null;
let heartbeatPingMsg = "pingMsg";
let timeout = 1000 * 60 * 2; // 响应超时时间
let responseTimer = null;
// import onlineUrl from "../../config/prod.env.js"; //生产环境配置
let wsuri = null;
// https://wxapi.bannao.net
// const baseUrl = onlineUrl.VUE_APP_BASE_URL.slice(1, -1);
const baseUrl = ''
const metaUrl = import.meta.env.VITE_APP_BASE_API
//生产环境、开发环境下都是线上时生效
if (metaUrl == baseUrl) {
wsuri = "";
} else {
wsuri = "";
}
wsuri = "";
// wsuri = "ws://192.168.1.110:19402/ws/getHeartBeat";
console.log('wsuri',wsuri)
/**
* 创建webSocket
* @param {*} callback 回调函数
* @param {*} path ws路径
* @param {*} pingMsg 心跳信息
*/
function createWebSocket(callback, pingMsg, erroCallback, timeoutCallback) {
if (pingMsg) {
heartbeatPingMsg = pingMsg;
}
global_callback = callback;
if (erroCallback) {
global_erroCallback = erroCallback;
} else {
global_erroCallback = null;
}
if (timeoutCallback) {
global_timeoutCallback = timeoutCallback;
} else {
global_timeoutCallback = null;
}
if (websock == null || typeof websock !== WebSocket) {
initWebSocket();
}
}
function initWebSocket() {
try {
websock = new WebSocket(wsuri);
} catch (error) {
console.error("WebSocket created failed:", error);
this.scheduleReconnect();
return;
}
websock.onopen = function() {
websocketOpen();
checkResponseTimeout();
};
websock.onmessage = function(e) {
checkResponseTimeout();
websocketonmessage(e);
};
websock.onclose = function(e) {
stopHeartbeat();
stopCheckResponseTimeout();
};
websock.onerror = function(error) {
// 尝试重连
scheduleReconnect(error);
stopCheckResponseTimeout();
websock.close();
};
}
/**
* 开启心跳,重置重连次数
*/
function websocketOpen() {
retries = 0;
startHeartbeat();
}
function startHeartbeat() {
heartbeatTimer = setInterval(() => {
sendSock(heartbeatPingMsg);
}, heartbeatInterval);
}
function stopHeartbeat() {
if (heartbeatTimer) {
clearInterval(heartbeatTimer);
heartbeatTimer = null;
}
}
/**
* 重连
*/
function scheduleReconnect(error) {
if (retries < maxRetries) {
if (reconnectTimer) {
clearTimeout(reconnectTimer);
}
reconnectTimer = setTimeout(() => {
retries++;
initWebSocket();
}, reconnectInterval);
} else {
global_erroCallback && global_erroCallback(error);
console.error("Max reconnect attempts exceeded");
}
}
// 数据接收
function websocketonmessage(msg) {
let result = null;
// 二进制文件
if (msg.data instanceof Blob) {
const reader = new FileReader();
reader.readAsText(msg.data, "UTF-8");
reader.onload = e => {
result = JSON.parse(reader.result);
global_callback && global_callback(result);
};
} else {
global_callback && global_callback(msg.data);
}
}
/**
* 发送数据
* 1. ws开启状态 直接发送
* @param {*} agentData
*/
function sendSock(agentData) {
if (websock && websock.readyState === websock.OPEN) {
// ws开启状态
websocketsend(agentData);
}
// websock.readyState:1, 正在链接中
// 正在开启中...
else if (websock.readyState === websock.CONNECTING) {
// 若是 正在开启状态,则等待1s后重新调用
setTimeout(function() {
sendSock(agentData);
}, 1000);
} else {
// 未开启 ,则等待1s后重新调用
setTimeout(function() {
sendSock(agentData);
}, 1000);
}
}
/**
* 检查响应超时
*/
function checkResponseTimeout() {
if (responseTimer) {
clearTimeout(responseTimer);
}
responseTimer = setTimeout(() => {
// 关闭连接
websock.close();
global_timeoutCallback && global_timeoutCallback();
}, timeout);
}
/**
* 停止检查超时
*/
function stopCheckResponseTimeout() {
responseTimer && clearTimeout(responseTimer);
}
// 数据发送
function websocketsend(agentData) {
websock.send(agentData);
}
/**
* 关闭连接
*/
function closeSock() {
if (websock) {
websock.close();
}
}
export { createWebSocket, closeSock, sendSock };
sockCountDown.js 状态封装
/**
* 定义socket
* res 返回状态
* status:start开始/padding 进行中/success,failed
* data:{} or []
* author:liuxuefeng
*/
import {createWebSocket,closeSock,sendSock} from './socketCommon.js'
import {CountdownTool} from './timer.js'
import { isEmpty} from "@/utils/stringUtils";
/**
*
* @param {*} pingMsg 对象
* @returns
*/
export function scoketCountDown(pingMsg){
return new Promise((resolve,reject)=>{
var countdownTool =new CountdownTool(()=>{
createWebSocket((res)=>{
console.log(res)
if(res=='mx' || isEmpty(res) )return
const result=JSON.parse(res);
if(result.status == 'over'){
console.log('结束了 webSocketCallBack');
countdownTool.close();
closeSock();
resolve(result.data)
}
},JSON.stringify(pingMsg))
},closeSock)
countdownTool.start().then(res=>{
console.log('结束了')
closeSock()
reject(res);
})
})
}
timer.js 计时器封装
/**
*
* @param {*} timeStamp 毫秒 多少毫秒后结束 默认一分钟结束
*
*/
export class CountdownTool{
constructor(callback,closeCallback,timeStamp=60000){
if(!typeof callback == 'function'){
throw new Error('need function ')
}
if(!typeof closeCallback == 'function'){
throw new Error('need function ')
}
this.callback=callback;
this.closeCallback=closeCallback;
this.timer=null;
this.timeStamp=timeStamp;
this.reverseNum=timeStamp/1000;
}
start(){
return new Promise((resolve,reject)=>{
var sTime= new Date().getTime();
this.callback();
this.timer=setInterval(()=>{
this.reverseNum=(sTime+this.timeStamp-new Date().getTime())/1000;
console.log(`倒计时中${this.reverseNum}`)
if(sTime+this.timeStamp<new Date().getTime()){
this.closeCallback()
clearInterval(this.timer);
resolve({code:'over Time',data:null});
}
},500)
})
}
close(){
clearInterval(this.timer);
}
}
具体引用
import {scoketCountDown} from ‘@/utils/socketUtils/socketCountDown.js’