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) => {},
})
相关推荐
iOS阿玮1 小时前
社交的本质是价值交换,请不要浪费别人的时间。
uni-app·app·apple
monika_yu1 小时前
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uni-app
2501_916007471 小时前
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
websocket·网络协议·tcp/ip·http·网络安全·https·udp
2501_916013741 小时前
使用 Windows 完成 iOS 应用上架:Appuploader对比其他证书与上传方案
websocket·网络协议·tcp/ip·http·网络安全·https·udp
济宁雪人2 小时前
HTTP协议
网络·网络协议·http
emo了小猫3 小时前
HTTP连接管理——短连接,长连接,HTTP 流水线
网络·网络协议·http
大阳光男孩3 小时前
Vue3 + UniApp 蓝牙连接与数据发送(稳定版)
uni-app
muyouking114 小时前
用 n8n 提取静态网页内容:从 HTTP Request 到 HTML 节点全解析
网络协议·http·html
浩浩测试一下15 小时前
Authpf(OpenBSD)认证防火墙到ssh连接到SSH端口转发技术栈 与渗透网络安全的关联 (RED Team Technique )
网络·网络协议·tcp/ip·安全·网络安全·php
Think Spatial 空间思维16 小时前
【实施指南】Android客户端HTTPS双向认证实施指南
android·网络协议·https·ssl