修复运行到支付宝小程序报错和websokcet连接问题

This commit is contained in:
2025-05-19 18:45:37 +08:00
parent 11ceead115
commit 447c8d1147
5 changed files with 528 additions and 99 deletions

View File

@@ -4,6 +4,7 @@ export default (params) => {
let data = params.data || {}; let data = params.data || {};
let type = params.type || 1; let type = params.type || 1;
let toast = params.toast || true; let toast = params.toast || true;
let userInfo=uni.cache.get('userInfo')||{id:''}
let header = { let header = {
version: uni.conf.version, version: uni.conf.version,
type: uni.getSystemInfoSync().platform, type: uni.getSystemInfoSync().platform,
@@ -20,9 +21,9 @@ export default (params) => {
platformType: 'ALI', platformType: 'ALI',
// #endif // #endif
token: uni.cache.get('token') || '', token: uni.cache.get('token') || '',
id: uni.cache.get('userInfo').id || '', id: userInfo.id ,
shopId: uni.cache.get('shopId') || '', shopId: uni.cache.get('shopId') || '',
userId: uni.cache.get('userInfo').id || '', userId:userInfo.id
} }
if (toast) { if (toast) {
uni.showLoading({ uni.showLoading({

View File

@@ -0,0 +1,350 @@
import {
ref,
onMounted,
onBeforeUnmount
} from 'vue';
const useWebSocket = (options = {}) => {
const {
heartbeatInterval = 10000, //心跳是10秒一次
reconnectInterval = 3000, //重新连接间隔时间的一个参数
maxReconnectAttempts = 3, //最大重连接次数
initialReconnectInterval = 3000, // 初始重连间隔
initMessage,
initMessageRetryCount = 3, // 新增:初始化消息发送重试次数
initMessageRetryInterval = 2000, // 新增:初始化消息重试间隔
maxReconnectDuration = Infinity
} = options;
const autoReconnect = ref(true); //是否自动重新连接
const socketTask = ref(null);
const isConnected = ref(false); //表示是否已连接上。
const heartbeatTimer = ref(null); //心跳定时器
const reconnectTimer = ref(null); //重连定时器
const reconnectAttempts = ref(0); //重连的尝试次数
const isNetworkConnected = ref(true); //监听当前网络连接状态
const isManuallyClosed = ref(false); //是否是被手动关闭的
const receivedMessages = ref(); //储从 WebSocket 服务器接收到的消息
const initMessageSendAttempts = ref(0); //初始化连接多少次
const reconnectStartTime = ref(0); //新增:记录重连开始时间
const isPongReceived = ref(false)
const allowReconnect = ref(true); // 新增:控制是否允许重连
// 关闭现有连接并清理资源
const closeExistingConnection = () => {
if (socketTask.value) {
// 关闭 WebSocket 连接
socketTask.value.close({
success: () => {
console.log('WebSocket 连接已关闭');
},
fail: (err) => {
console.error('关闭 WebSocket 连接失败:', err);
}
});
// 清除心跳定时器
clearInterval(heartbeatTimer.value);
heartbeatTimer.value = null;
// 清除重连定时器
clearTimeout(reconnectTimer.value);
reconnectTimer.value = null;
// 标记连接已断开
isConnected.value = false;
}
};
// 连接 WebSocket
const connect = () => {
if (!isNetworkConnected.value) {
uni.showToast({
title: '网络未连接...',
icon: 'none'
})
setTimeout(() => {
uni.pro.switchTab('index/index')
}, 1000)
console.log('网络未连接,暂不尝试连接 WebSocket');
return;
}
// 关闭现有连接并清理资源
closeExistingConnection();
socketTask.value = uni.connectSocket({
url: uni.conf.baseUrlwws,
success: (res) => {
isConnected.value = true;
// 监听初始化成功在开启心跳
startHeartbeat();
},
fail: () => {
console.error('WebSocket 连接失败,尝试重连');
if (autoReconnect.value && allowReconnect.value) {
handleReconnect();
}
}
});
if (socketTask.value) {
socketTask.value.onOpen(() => {
// 初始化 初始购物车
sendMessage(initMessage)
});
socketTask.value.onMessage((res) => {
receivedMessages.value = JSON.parse(res.data)
// receivedMessages.value.push(list);
if (receivedMessages.value == 'ok' || receivedMessages.value.operate_type == 'init') {
console.log('初始化正常,心跳响应正常');
// 清除重连定时器
clearTimeout(reconnectTimer.value);
allowReconnect.value = false
reconnectTimer.value = null;
}
});
socketTask.value.onClose((res) => {
console.log(res, 'WebSocket 连接已关闭,尝试重连');
isConnected.value = false;
clearInterval(heartbeatTimer.value); // 停止心跳定时器
clearTimeout(reconnectTimer.value); // 清除重连定时器
if (res.code == '1006' && !allowReconnect.value) {
uni.showToast({
title: '网络异常,请重新扫码',
icon: 'none'
});
autoReconnect.value = false;
setTimeout(() => {
uni.pro.switchTab('index/index');
}, 1000)
return false;
}
if (autoReconnect.value && !isManuallyClosed.value) {
handleReconnect();
}
});
socketTask.value.onError((err) => {
console.error('WebSocket 连接发生错误:', err);
isConnected.value = false;
clearInterval(heartbeatTimer.value);
if (autoReconnect.value && !isManuallyClosed.value) {
handleReconnect();
}
});
} else {
console.error('socketTask 未正确初始化');
}
};
// 启动心跳机制
const startHeartbeat = () => {
if (!isNetworkConnected.value) {
console.log('网络未连接,暂停心跳');
uni.showToast({
title: '网络未连接...',
icon: 'none'
});
setTimeout(() => {
uni.pro.switchTab('index/index');
}, 1000);
return;
}
heartbeatTimer.value = setInterval(() => {
if (isConnected.value) {
console.log('发送心跳消息');
isPongReceived.value = false; // 每次发送心跳消息前重置标记
socketTask.value.send({
data: JSON.stringify({
type: 'ping_interval',
set: 'shopping'
}),
success: () => {
console.log('心跳消息发送成功');
const pongTimer = setTimeout(() => {
if (!isPongReceived.value) {
console.error('心跳超时,未收到响应,尝试重连');
clearInterval(heartbeatTimer.value);
if (autoReconnect.value && reconnectAttempts.value <
maxReconnectAttempts && allowReconnect.value) {
handleReconnect();
} else {
console.error('重连次数达到上限,停止重连和心跳');
clearInterval(heartbeatTimer.value);
autoReconnect.value = false;
uni.pro.switchTab('index/index');
}
}
}, heartbeatInterval * 1.2);
const handlePong = (res) => {
try {
let data = JSON.parse(res.data);
if (data.operate_type == "init" || (data.msg === 'ok' &&
data.msg_id ==
'ping_interval')) {
isPongReceived.value = true;
console.log('收到心跳响应,清除超时定时器');
clearTimeout(pongTimer);
}
} catch (error) {
console.error('解析心跳响应数据时出错:', error);
}
};
socketTask.value.onMessage(handlePong);
},
fail: () => {
console.error('心跳消息发送失败,尝试重连');
clearInterval(heartbeatTimer.value);
if (autoReconnect.value && reconnectAttempts.value <
maxReconnectAttempts && allowReconnect.value) {
handleReconnect();
} else {
console.error('重连次数达到上限,停止重连和心跳');
clearInterval(heartbeatTimer.value);
autoReconnect.value = false;
uni.pro.switchTab('index/index');
}
}
});
}
}, heartbeatInterval);
};
// 手动关闭连接
const closeSocket = () => {
isManuallyClosed.value = true;
closeExistingConnection();
};
// 发送消息
const sendMessage = async (data) => {
if (isConnected.value) {
await socketTask.value.send({
data: JSON.stringify(data),
success: () => {
// console.log('消息发送成功');
},
fail: () => {
// console.error('消息发送失败');
}
});
} else {
console.error('WebSocket 未连接,无法发送消息');
}
};
// 处理重连逻辑
const handleReconnect = () => {
if (!isNetworkConnected.value) {
console.log('网络未连接,暂停重连');
return;
}
if (isManuallyClosed.value) {
console.log('手动关闭连接,不进行重连');
return;
}
if (!allowReconnect.value) {
console.log('重连功能已关闭,不进行重连');
return;
}
if (reconnectAttempts.value < maxReconnectAttempts) {
reconnectAttempts.value++;
const reconnectInterval = initialReconnectInterval * Math.pow(2, reconnectAttempts.value - 1);
const randomizedInterval = reconnectInterval + Math.floor(Math.random() * 1000);
uni.showLoading({
title: `正在努力连接..`,
mask: true
})
console.log(`尝试第 ${reconnectAttempts.value} 次重连,重连间隔: ${randomizedInterval}ms...`);
reconnectTimer.value = setTimeout(() => {
connect();
}, randomizedInterval);
} else {
console.error('重连次数达到上限,停止重连');
uni.showToast({
title: '重连次数达到上限,停止重连',
icon: 'none'
});
clearInterval(heartbeatTimer.value);
autoReconnect.value = false;
setTimeout(() => {
uni.hideLoading();
uni.pro.switchTab('index/index');
}, 1000)
}
};
// / 网络状态监听
const initNetworkListener = () => {
uni.getSystemInfo({
success: (res) => {
if (res.platform !== 'devtools') {
uni.onNetworkStatusChange((statusRes) => {
isNetworkConnected.value = statusRes.isConnected;
if (statusRes.isConnected && !isManuallyClosed.value) {
console.log('网络已连接,尝试重新连接 WebSocket');
if (!isConnected.value && autoReconnect.value) {
connect();
}
} else if (!statusRes.isConnected) {
console.log('网络已断开,暂停 WebSocket 操作');
clearInterval(heartbeatTimer.value);
clearTimeout(reconnectTimer.value);
if (socketTask.value) {
socketTask.value.close();
isConnected.value = false;
}
}
});
}
},
fail: (err) => {
console.error('获取系统信息失败:', err);
}
});
uni.getNetworkType({
success: (res) => {
isNetworkConnected.value = res.networkType !== 'none';
if (!isNetworkConnected.value) {
console.log('初始网络未连接,暂不尝试连接 WebSocket');
}
}
});
};
// 页面显示,尝试连接 WebSocket
const onShowconnect = () => {
if (autoReconnect.value) {
uni.showLoading({
title: `尝试再次连接`,
mask: true
})
connect();
}
}
onBeforeUnmount(() => {
closeSocket();
});
return {
isConnected,
sendMessage,
closeSocket,
receivedMessages,
closeExistingConnection,
onShowconnect,
initNetworkListener
};
};
export default useWebSocket;

View File

@@ -31,6 +31,18 @@ const useWebSocket = (options = {}) => {
const allowReconnect = ref(true); // 新增:控制是否允许重连 const allowReconnect = ref(true); // 新增:控制是否允许重连
// 关闭现有连接并清理资源 // 关闭现有连接并清理资源
const closeExistingConnection = () => { const closeExistingConnection = () => {
// 清除心跳定时器
clearInterval(heartbeatTimer.value);
heartbeatTimer.value = null;
// 清除重连定时器
clearTimeout(reconnectTimer.value);
reconnectTimer.value = null;
// 标记连接已断开
isConnected.value = false;
uni.closeSocket()
if (socketTask.value) { if (socketTask.value) {
// 关闭 WebSocket 连接 // 关闭 WebSocket 连接
socketTask.value.close({ socketTask.value.close({
@@ -72,7 +84,7 @@ const useWebSocket = (options = {}) => {
// 关闭现有连接并清理资源 // 关闭现有连接并清理资源
closeExistingConnection(); closeExistingConnection();
socketTask.value = uni.connectSocket({ uni.connectSocket({
url: uni.conf.baseUrlwws, url: uni.conf.baseUrlwws,
success: (res) => { success: (res) => {
isConnected.value = true; isConnected.value = true;
@@ -87,6 +99,63 @@ const useWebSocket = (options = {}) => {
} }
}); });
uni.onSocketOpen(function(res) {
console.log('WebSocket连接已打开');
sendMessage(initMessage)
});
function sendSocketMessage(msg) {
if (isConnected.value) {
uni.sendSocketMessage({
data: msg
});
} else {
socketMsgQueue.push(msg);
}
}
uni.onSocketError(function(res) {
console.log('WebSocket连接打开失败请检查');
console.error('WebSocket 连接发生错误:', err);
isConnected.value = false;
clearInterval(heartbeatTimer.value);
if (autoReconnect.value && !isManuallyClosed.value) {
handleReconnect();
}
});
uni.onSocketMessage(function(res) {
console.log('收到服务器内容:' + res.data);
receivedMessages.value = JSON.parse(res.data)
// receivedMessages.value.push(list);
if (receivedMessages.value == 'ok' || receivedMessages.value.operate_type == 'init') {
console.log('初始化正常,心跳响应正常');
// 清除重连定时器
clearTimeout(reconnectTimer.value);
allowReconnect.value = false
reconnectTimer.value = null;
}
});
uni.onSocketClose(function(res) {
console.log('WebSocket 已关闭!');
console.log(res, 'WebSocket 连接已关闭,尝试重连');
isConnected.value = false;
clearInterval(heartbeatTimer.value); // 停止心跳定时器
clearTimeout(reconnectTimer.value); // 清除重连定时器
if (res.code == '1006' && !allowReconnect.value) {
uni.showToast({
title: '网络异常,请重新扫码',
icon: 'none'
});
autoReconnect.value = false;
setTimeout(() => {
uni.pro.switchTab('index/index');
}, 1000)
return false;
}
if (autoReconnect.value && !isManuallyClosed.value) {
handleReconnect();
}
});
if (socketTask.value) { if (socketTask.value) {
socketTask.value.onOpen(() => { socketTask.value.onOpen(() => {
// 初始化 初始购物车 // 初始化 初始购物车
@@ -223,8 +292,8 @@ const useWebSocket = (options = {}) => {
// 发送消息 // 发送消息
const sendMessage = async (data) => { const sendMessage = async (data) => {
if (isConnected.value) { if (isConnected.value) {
await socketTask.value.send({ uni.sendSocketMessage({
data: JSON.stringify(data), data:JSON.stringify(data),
success: () => { success: () => {
// console.log('消息发送成功'); // console.log('消息发送成功');
}, },
@@ -232,6 +301,15 @@ const useWebSocket = (options = {}) => {
// console.error('消息发送失败'); // console.error('消息发送失败');
} }
}); });
// await socketTask.value.send({
// data: JSON.stringify(data),
// success: () => {
// // console.log('消息发送成功');
// },
// fail: () => {
// // console.error('消息发送失败');
// }
// });
} else { } else {
console.error('WebSocket 未连接,无法发送消息'); console.error('WebSocket 未连接,无法发送消息');
} }
@@ -252,7 +330,7 @@ const useWebSocket = (options = {}) => {
console.log('重连功能已关闭,不进行重连'); console.log('重连功能已关闭,不进行重连');
return; return;
} }
if (reconnectAttempts.value < maxReconnectAttempts) { if (reconnectAttempts.value < maxReconnectAttempts) {
reconnectAttempts.value++; reconnectAttempts.value++;
const reconnectInterval = initialReconnectInterval * Math.pow(2, reconnectAttempts.value - 1); const reconnectInterval = initialReconnectInterval * Math.pow(2, reconnectAttempts.value - 1);

View File

@@ -56,7 +56,7 @@
// 关闭模态框 // 关闭模态框
const closeModal = () => { const closeModal = () => {
emits('close'); emits('close');
password = ''; password.value = '';
}; };
// 将方法暴露给父组件 // 将方法暴露给父组件
defineExpose({ defineExpose({

View File

@@ -1,93 +1,93 @@
{ {
"name": "wepp", "name" : "wepp",
"appid": "__UNI__9EC799C", "appid" : "__UNI__9EC799C",
"description": "", "description" : "",
"versionName": "1.0.0", "versionName" : "1.0.0",
"versionCode": "100", "versionCode" : "100",
"transformPx": false, "transformPx" : false,
/* 5+App */ /* 5+App */
"app-plus": { "app-plus" : {
"usingComponents": true, "usingComponents" : true,
"nvueStyleCompiler": "uni-app", "nvueStyleCompiler" : "uni-app",
"compilerVersion": 3, "compilerVersion" : 3,
"splashscreen": { "splashscreen" : {
"alwaysShowBeforeRender": true, "alwaysShowBeforeRender" : true,
"waiting": true, "waiting" : true,
"autoclose": true, "autoclose" : true,
"delay": 0 "delay" : 0
}, },
/* */ /* */
"modules": {}, "modules" : {},
/* */ /* */
"distribute": { "distribute" : {
/* android */ /* android */
"android": { "android" : {
"permissions": [ "permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>", "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>", "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>", "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>", "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>", "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>", "<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>", "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>", "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>", "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>", "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>", "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>", "<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
] ]
}, },
/* ios */ /* ios */
"ios": {}, "ios" : {},
/* SDK */ /* SDK */
"sdkConfigs": {} "sdkConfigs" : {}
} }
}, },
/* */ /* */
"quickapp": {}, "quickapp" : {},
/* */ /* */
"mp-weixin": { "mp-weixin" : {
"appid": "wxd88fffa983758a30", "appid" : "wxd88fffa983758a30",
"setting": { "setting" : {
"urlCheck": false, "urlCheck" : false,
"minified": true, "minified" : true,
"es6": true, "es6" : true,
"postcss": true "postcss" : true
}, },
"usingComponents": true, "usingComponents" : true,
"libVersion": "latest", "libVersion" : "latest",
"permission": { "permission" : {
"scope.userLocation": { "scope.userLocation" : {
"desc": "你的位置信息将用于小程序位置接口的效果展示" "desc" : "你的位置信息将用于小程序位置接口的效果展示"
} }
}, },
"requiredPrivateInfos": ["getLocation", "onLocationChange", "chooseLocation", "chooseAddress"], "requiredPrivateInfos" : [ "getLocation", "onLocationChange", "chooseLocation", "chooseAddress" ],
"optimization": { "optimization" : {
"filterUnused": false "filterUnused" : false
} }
}, },
"h5": {}, "h5" : {},
"mp-alipay": { "mp-alipay" : {
"usingComponents": true, "usingComponents" : true,
"appid": "2021004145625815", "appid" : "2021004145625815",
"devServer": { "devServer" : {
"autoOpen": true // 设置为true自动打开支付宝小程序 "autoOpen" : true // 设置为true自动打开支付宝小程序
}, },
"unipush": { "unipush" : {
"enable": false "enable" : false
} }
}, },
"mp-baidu": { "mp-baidu" : {
"usingComponents": true "usingComponents" : true
}, },
"mp-toutiao": { "mp-toutiao" : {
"usingComponents": true "usingComponents" : true
}, },
"uniStatistics": { "uniStatistics" : {
"enable": false "enable" : false
}, },
"vueVersion": "3" "vueVersion" : "3"
} }