WebSocket断开重连机制 实现demo,非采用onclose事件方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebSocket断开重连机制 实现demo,非采用onclose事件方式相关的知识,希望对你有一定的参考价值。

参考技术A WebSocket.onclose 事件监听器 ,不可控性和断网情况下不触发问题,无法很好实现断线重连功能。

我们解决方案是,根据服务端一定时间,自动给客户端推送的心跳,心跳来判断是否断开,如果一定时间内没有收到服务器发送的心跳,则会触发重连。(很像医生抢救重症病人,看心跳图没有波动,启用心电复苏)

uniapp即时聊天 websocket封装(建立连接断线重连心跳机制主动关闭)

  1. 使用 SocketTask 的方式去管理 webSocket 链接,每一条链路的生命周期都更加可控
  2. 可实现主动建立连接、心跳防断线机制、断线主动重连、提供主动断开的方法

一、如何使用 (uniapp Vue3)

<template>
  // ...
</template>

<script setup>
  import WS from './websocket'
  import  onLoad, onUnload  from '@dcloudio/uni-app'
  
  // 进入聊天页面初始化
  let ws = null
  onLoad((options) => 
    ws = new WS(
      // 连接websocket所需参数
      data:  userId: options.userId ,
      // 首次连接成功之后,断线重新连接后也会触发(防止断线期间对方发送消息未接收到)
      onConnected: () => 
        // toDo
        // 一般用于请求历史消息列表 getHistoryList()
      ,
      // 监听接收到服务器消息
      onMessage: (data) => 
        // toDo
        // 一般用于将最新的一条消息展示在页面上
      
    )
  )
  
  // 发送消息
  function sendMsg() 
    uni.request(
      url: '后端url',
      data: ...,
      success: () => 
        // 发送成功后,上方onMessage会接收到最新消息
      
    )
  
  
  // 页面销毁,断开websocket
  onUnload(() => 
    // 主动关闭websocket
    ws.close()
  )
</script>

二、websocket类代码

// 心跳间隔、重连websocket间隔,5秒
const interval = 5000
// 重连最大次数
const maxReconnectMaxTime = 5

export default class WS 
  constructor(options) 
    // 配置
    this.options = options
    // WS实例
    this.socketTask = null

    // 连接中
    // 是否是正常关闭
    this.normalClose = false
    // 重新连接次数
    this.reconnectTime = 1
    // 重新连接Timer
    this.reconnectTimer = null
    // 心跳Timer
    this.heartTimer = null

    // 发起连接
    this.initWS()

    // 关闭WS
    this.close = () => 
      this.normalClose = true
      this.socketTask.close()
      clearInterval(this.heartTimer)
    
  

  initWS() 
    // this.options.data 连接websocket所需参数
    const url = 'wss://后端url' + this.options.data.userId
    this.socketTask = uni.connectSocket( url, success()  )
    // 监听WS
    this.watchWS()
  

  watchWS() 
    // 监听 WebSocket 连接打开事件
    this.socketTask.onOpen(() => 
      console('websocket连接成功!')
      // 连接成功
      this.options.onConnected()
      // 重置连接次数
      this.reconnectTime = 1
      // 发送心跳
      this.onHeartBeat()
      // 监听消息
      this.onMessage()
      // 关闭Toast
      uni.hideLoading()
    )

    // 监听websocket 错误
    this.socketTask.onError((res) => 
      this.socketTask.close()
      this.onDisconnected(res)
    )

    // 监听 WebSocket 连接关闭事件
    this.socketTask.onClose((res) => 
      // 非正常关闭
      if (!this.normalClose) 
        this.onDisconnected(res)
      
    )
  

  // 监听消息
  onMessage() 
    // 监听websocket 收到消息
    this.socketTask.onMessage((res) => 
      //收到消息
      if (res.data) 
        this.options.onMessage(JSON.parse(res.data))
       else 
        console('未监听到消息:原因:', JSON.stringify(res))
      
    )
  

  // 断开连接
  onDisconnected(res) 
    console('websocket断开连接,原因:', JSON.stringify(res))
    // 关闭心跳
    clearTimeout(this.heartTimer)
    // 全局Toast提示,防止用户继续发送
    uni.showLoading( title: '消息收取中…' )
    // 尝试重新连接
    this.onReconnect()
  

  // 断线重连
  onReconnect() 
    clearTimeout(this.reconnectTimer)
    if (this.reconnectTime < maxReconnectMaxTime) 
      this.reconnectTimer = setTimeout(() => 
        console.log(`第【$this.reconnectTime】次重新连接中……`)
        this.initWS()
        this.reconnectTime++
      , interval)
     else 
      uni.showModal(
        title: '温馨提示',
        content: '服务器开小差啦~请返回聊天列表重试',
        showCancel: false,
        confirmText: '我知道了',
        success: () => 
          uni.navigateBack()
        
      )
    
  

  /** @心跳 **/
  onHeartBeat() 
    this.heartTimer = setInterval(() => 
      this.socketTask.send(
        data: `heart:$this.options.data.userId`,
        success() 
          console.log('心跳发送成功!')
        
      )
    , interval)
  


以上是关于WebSocket断开重连机制 实现demo,非采用onclose事件方式的主要内容,如果未能解决你的问题,请参考以下文章

维护websocket长链接的稳定

uniapp即时聊天 websocket封装(建立连接断线重连心跳机制主动关闭)

uniapp即时聊天 websocket封装(建立连接断线重连心跳机制主动关闭)

初探和实现websocket心跳重连

初探和实现WebSocket心跳重连

js websocket 心跳检测,断开重连,超时重连