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) => {},
})
相关推荐
bu_shuo2 小时前
IP相关知识
网络·网络协议·tcp/ip
2501_916008893 小时前
2026 iOS 证书管理,告别钥匙串依赖,构建可复制的签名环境
android·ios·小程序·https·uni-app·iphone·webview
黄昏回响4 小时前
计算机系统基础知识(九):软件篇之网络协议详解
网络·网络协议·面试·改行学it
哆啦code梦5 小时前
SSE与WebSocket:实时通信选型指南与实现示例
websocket·sse·ws·wss
serve the people5 小时前
ACME 协议流程与AllinSSL 的关系(二)
网络协议·https·ssl
weixin_425023006 小时前
【Spring Boot 2.7 整合 WebSocket 完整实战】鉴权拦截+在线用户管理+定向消息推送
spring boot·后端·websocket
honor_zhang6 小时前
Vue3使用@vueuse/core集成Websocket实战及携带身份信息的3种方式
websocket·网络协议·身份验证
独断万古他化6 小时前
【Java 实战项目】多用户网页版聊天室:项目总览与用户 & 好友管理模块实现
java·spring boot·后端·websocket·mybatis
zl_dfq7 小时前
计算机网络 之 【http协议】(http的无状态性、Cookie与Session的简介)
网络协议·计算机网络·http
添砖java‘’7 小时前
应用层协议HTTP
网络·网络协议·http