Uniapp:WebSocket 重连之后累加触发 uni.onSocketOpen()

省流

  • 不要用 uni.xxx 那一套,用 socketTask = await uni.connectSocket({}) socketTask 去控制

业务逻辑描述

  1. 第一次进入应用主页,连接 WebSocket
  2. 手机熄屏之后,断开当前连接的 WebSocket
  3. 手机亮屏之后,再次进入应用后,重新连接 WebSocket 服务

问题

  • 亮屏之后,再次进入应用,WebSocket 会累加,导致我发送的心跳包:

  • 第一次熄屏亮起,会在短时间内发送两次

  • 第二次熄屏亮起,会在短时间内发送三次

  • ...累加

问题截图

问题代码

大概就是这套逻辑

用的都是 uni.xxx 这套,问题就出现在这里了

javascript 复制代码
import { handleSocketMessage } from './websocketUtils'
import Nav2Login from '@/utils/request/modelNavigateToLogin'
let socketOpen = false
let socketMsgQueue: any = []
let heartbeatTimer: any | null = null

async function startWebsocketServer() {
  if (heartbeatTimer) {
    clearInterval(heartbeatTimer)
    heartbeatTimer = null
  }
  if (socketOpen) {
    await closeWebSocket()
  }
  await uni
    .connectSocket({
      url: WS_URL,
    })
    .then((res) => {
     
    })

  /**
   * 问题:
   * https://ask.dcloud.net.cn/question/149762
   */
  uni.onSocketOpen(function (res: any) {
    socketOpen = true
    for (var i = 0; i < socketMsgQueue.length; i++) {
      sendSocketMessage(socketMsgQueue[i])
    }
    socketMsgQueue = []
  })

  /**
   * 这里会有熄屏累积次数的效果
   */
  uni.onSocketMessage(function (res) {
    console.log('收到服务器内容:' + res.data)
    handleSocketMessage(res.data)
  })
}

function sendSocketMessage(msg: any) {
  if (socketOpen) {
    uni.sendSocketMessage({
      data: msg,
    })
  } else {
    socketMsgQueue.push(msg)
  }
}

/**
 * 关闭WebSocket连接
 */
export function closeWebSocket() {
  return new Promise((resolve, reject) => {
    uni.closeSocket({
      success: function (res) {
        console.log('WebSocket关闭成功!:>>', res)
        socketOpen = false
        clearInterval(heartbeatTimer)
        heartbeatTimer = null
        console.log('清除心跳定时器')
        resolve('Close Socket Success')
      },
      fail: function (res) {
        console.log('WebSocket关闭失败!:>>', res)
        reject('Close Socket Reject')
      },
      complete: () => {
        // console.log('complete')
      },
    })
  })
}
export default startWebsocketServer

解决之后的截图

解决的代码框架,参考官方文档

typescript 复制代码
let socketTask: any = null
//  complete: (res) => {}, 一定要有
socketTask = await uni.connectSocket({
  url: WS_URL,
  complete: (res) => {},
})
socketTask.onOpen(() => {})
socketTask.onMessage((res: any) => {})
socketTask.close({
  success: (res: any) => {},
  fail: (res: any) => {},
})
相关推荐
钛态1 小时前
Flutter 三方库 http_mock_adapter — 赋能鸿蒙应用开发的高效率网络接口 Mock 与自动化测试注入引擎(适配鸿蒙 HarmonyOS Next ohos)
android·网络协议·flutter·http·华为·中间件·harmonyos
2501_915918412 小时前
苹果App Store上架审核卡住原因分析与解决方案指南
android·ios·小程序·https·uni-app·iphone·webview
IT小白33 小时前
windows的VMware虚拟机上的Linux系统(CentOS)配置永久ip(关机重启ip不变)
网络·网络协议·tcp/ip
蛊明5 小时前
批量检测 IP 是否在线:CPing vs QuickPing
网络·网络协议·tcp/ip
路由侠内网穿透.5 小时前
本地部署开源书签管理工具 LinkAce 并实现外部访问( Linux 版本)
linux·运维·服务器·网络·网络协议·开源
honor_zhang9 小时前
Spring Boot集成Websocket服务以及连接时需要注意的问题
spring boot·后端·websocket
小钻风336611 小时前
在 Spring Boot 项目中使用 WebSocket 实现实时通信
websocket
程序员大飞哥11 小时前
T-Box双SIM卡的"幻觉":为什么有两张卡却还在断连?
网络协议
HWL567911 小时前
uni-app的生命周期
前端·vue.js·uni-app
一颗小青松11 小时前
uniapp设置安卓 ios 自定义启动页
uni-app