page code
<template><view class="container">/////</view> </template><script>import socket from '@/util/socket';export default {data() {return {};},onLoad() {console.log('页面加载了,initWebSocket')this.initWebSocket();},onUnload() {console.log('监听页面卸载 ,initWebSocket')// 清理 WebSocket 客户端this.cleanupWebSocket();},onShow(){console.log('页面显示了,initWebSocket')this.initWebSocket();this.getUser();},onHide(){console.log('页面隐藏了,清理 WebSocket 客户端')this.cleanupWebSocket();},methods: { initWebSocket() {// 启动 WebSocket 客户端console.log(44331)socket.socket.connect();},cleanupWebSocket() {// 清理 WebSocket 客户端资源if (socket.socket) {socket.socket.cleanup();}}},} </script><style lang="scss" scoped> //// </style>
/util/socket.js文件内容
import { socket_url } from '@/common/config'; // 确保路径正确 class WebSocketClient {constructor(url = socket_url) {this.url = url;this.socketTask = null;this.time = null;this.reconnectAttempts = 0; // 重连尝试次数this.maxReconnectAttempts = Infinity; // 默认为无限次重连this.isConnecting = false; // 防止重复连接this.autoConnectInterval = 1200; // 自动连接间隔时间,默认5秒this.pingInterval = 2000; // 心跳检测间隔时间,默认8秒this.lastPongTime = Date.now(); // 上次收到pong的时间 }connect() {console.log(this.isConnecting)console.log(this.socketTask)if (this.isConnecting || this.socketTask) return;this.cleanup(); // 清除旧的 socketTask 和事件监听器this.bindEvents(); // 先绑定事件监听器this.isConnecting = true;console.log('尝试连接...');this.socketTask = uni.connectSocket({url: this.url,success: () => {console.log('connectSocket 请求已发出');},fail: (err) => {console.error('connectSocket 请求失败:', err);this.handleError();}});}bindEvents() {const that = this;// 绑定 onOpen 事件uni.onSocketOpen(() => {console.log('WebSocket 已打开');that.isConnecting = false;that.reconnectAttempts = 0; // 重置重连尝试次数 that.setConnect();that.startPingPong(); // 启用心跳检测 });// 绑定 onMessage 事件uni.onSocketMessage((res) => {let data = res.data;console.log("WebSocket 收到消息:" + data);try {data = JSON.parse(data);} catch (e) {console.log('ws接收到非对象数据', data);return;}var type = data.type || '';switch(type){case 'get_client_id':that.bindUid(data.data.client_id);break;case "xxxxxx"://xxxxxbreak;}if (type === 'pong') {that.lastPongTime = Date.now();console.log('收到 pong 响应');}});// 绑定 onError 事件uni.onSocketError(() => {console.warn('WebSocket 错误');that.handleError();});// 绑定 onClose 事件uni.onSocketClose(() => {console.warn('WebSocket 已关闭');that.handleError();});}handleError() {this.socketTask = null;this.isConnecting = false;this.reconnectAttempts++;console.warn(`尝试重新连接 (${this.reconnectAttempts})`);setTimeout(() => {this.connect(); // 尝试重新连接}, this.autoConnectInterval); // 每5秒尝试一次重连 }setConnect() {console.log('WebSocket 建立连接');}startPingPong() {clearInterval(this.time); // 先清除计时器this.time = setInterval(() => {const now = Date.now();if (now - this.lastPongTime > this.pingInterval * 2) {console.warn('心跳超时,尝试重新连接');this.handleError();} else {console.log('发送 ping');uni.sendSocketMessage({data: JSON.stringify({ type: 'ping' })}).catch(err => {console.error('发送心跳检测消息失败:', err);});}}, this.pingInterval);}bindUid(client_id) {console.log('WebSocket 绑定客户端id' + client_id);let organise_id = uni.getStorageSync('organise_id');let admin_id = uni.getStorageSync('admin_id');if (organise_id && admin_id) {uni.$u.api.postBindAppAdminClientId({ client_id, organise_id, admin_id }).then(res => {if (res.code == 1) {console.log('绑定成功');}});}}cleanup() {// 关闭现有的 socketTask 并设置为 nullif (this.socketTask) {this.socketTask.close();this.socketTask = null;}// 清除心跳检测定时器clearInterval(this.time);// 清除自动连接定时器if (this.autoConnectTimer) clearInterval(this.autoConnectTimer);} }// 创建单例并导出 const socketInstance = new WebSocketClient(socket_url); // 替换为实际的 WebSocket URL export default {socket: socketInstance };