uni-app中在两个页面都定义了socket对象,页面跳转时webSocket对象无法正常关闭

uni-app中在两个页面都定义了socket对象,页面跳转时webSocket对象无法正常关闭

类别 信息
产品分类 uniapp/小程序/微信
开发环境 Windows
操作系统版本 windows10
HBuilderX类型 正式
HBuilderX版本 3.99
工具版本号 1.06.2402021
基础库版本 3.41
项目创建方式 HBuilderX

操作步骤:

在A页面使用uni.navigateTo方法跳转到B页面,在B页面中onUnload()方法中调用了socket.close方法关闭在B页面onLoad时创建的socket对象,重复几次以后就提示socket连接到达上限,在B页面中没能正常关闭socket连接

预期结果:

在B页面中定义的socket对象,应该在onUnload方法中使用socket.close时关闭对应的socket连接

实际结果:

在B页面中定义的socket对象,在onUnload方法中使用socket.close时调用的是A页面中socket对象的close方法

bug描述:

function createSocket() {  
    const url = xxx;  
    socket = uni.connectSocket({  
        url: url,  
        complete: () => {  

        }  
    });  

    uni.onSocketOpen(function(res) {  
        console.log('WebSocket connection opened111111');  
        startHeartBeat(socket);  
    });  

    uni.onSocketError(function(error) {  
        console.error('WebSocket error:', error);  
    });  

    uni.onSocketMessage(function(message) {  
        loadInfo();  
    });  

    uni.onSocketClose(function() {  
        console.log('WebSocket connection closed111');  
        clearInterval(heartInterval);  
    });  
}  
```
在A,B两个页面中都通过上述方式创建了一个socket对象,A页面为TabBar类型的页面,可从A页面跳转到B页面,也可从B返回A,在B页面返回A页面时,在生命周期函数onUnload()方法中,调用socket.close()方法,执行的不是B页面中socket对象的close方法而是A页面socket对象的close()方法,导致在页面切换时会一直累加socket连接,无法正确关闭B页面中的socket对象
```

更多关于uni-app中在两个页面都定义了socket对象,页面跳转时webSocket对象无法正常关闭的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于uni-app中在两个页面都定义了socket对象,页面跳转时webSocket对象无法正常关闭的实战教程也可以访问 https://www.itying.com/category-93-b0.html


uni-app 中,如果在两个页面中都定义了 WebSocket 对象,并且在页面跳转时没有正确关闭 WebSocket 连接,可能会导致连接无法正常关闭或重复连接的问题。为了避免这种情况,你可以采取以下措施:

1. 在页面离开时手动关闭 WebSocket

uni-app 中,可以通过监听页面的生命周期钩子来手动关闭 WebSocket 连接。例如,在 onUnload 生命周期钩子中关闭 WebSocket 连接。

export default {
  data() {
    return {
      socket: null
    };
  },
  onLoad() {
    this.socket = new WebSocket('ws://your-websocket-url');
    this.socket.onopen = () => {
      console.log('WebSocket connected');
    };
    this.socket.onmessage = (event) => {
      console.log('Message from server:', event.data);
    };
  },
  onUnload() {
    if (this.socket) {
      this.socket.close();
      console.log('WebSocket closed');
    }
  }
};

2. 使用全局 WebSocket 对象

为了避免在多个页面中重复创建 WebSocket 对象,可以将 WebSocket 对象定义在全局范围内(例如在 App.vue 中),然后在各个页面中通过事件或状态管理来与 WebSocket 交互。

// App.vue
export default {
  onLaunch() {
    this.globalData.socket = new WebSocket('ws://your-websocket-url');
    this.globalData.socket.onopen = () => {
      console.log('WebSocket connected');
    };
    this.globalData.socket.onmessage = (event) => {
      console.log('Message from server:', event.data);
    };
  },
  onUnload() {
    if (this.globalData.socket) {
      this.globalData.socket.close();
      console.log('WebSocket closed');
    }
  },
  globalData: {
    socket: null
  }
};

在页面中使用全局 WebSocket 对象:

// Page.vue
export default {
  onLoad() {
    const socket = getApp().globalData.socket;
    socket.onmessage = (event) => {
      console.log('Message from server:', event.data);
    };
  }
};

3. 使用 Vuex 管理 WebSocket 状态

如果你使用了 Vuex 进行状态管理,可以将 WebSocket 相关的逻辑放在 Vuex 中,并在页面中通过 VuexWebSocket 交互。

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    socket: null
  },
  mutations: {
    setSocket(state, socket) {
      state.socket = socket;
    },
    closeSocket(state) {
      if (state.socket) {
        state.socket.close();
        state.socket = null;
      }
    }
  },
  actions: {
    connectSocket({ commit }) {
      const socket = new WebSocket('ws://your-websocket-url');
      socket.onopen = () => {
        console.log('WebSocket connected');
      };
      socket.onmessage = (event) => {
        console.log('Message from server:', event.data);
      };
      commit('setSocket', socket);
    },
    disconnectSocket({ commit }) {
      commit('closeSocket');
    }
  }
});

在页面中使用 Vuex 管理 WebSocket

// Page.vue
export default {
  onLoad() {
    this.$store.dispatch('connectSocket');
  },
  onUnload() {
    this.$store.dispatch('disconnectSocket');
  }
};
回到顶部