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

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

uniapp即时聊天 websocket封装(建立连接、断线重连、心跳机制、主动关闭)_第1张图片

一、如何使用 (uniapp Vue3)





二、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,uni-app,网络协议)