typescript + vue3 实现websocket+心跳机制写入 纯代码记录

本文介绍了一个基于Vue和JavaScript的WebSocket实现方案,通过加入心跳包机制确保客户端与服务器之间的稳定连接。该方案实现了自动重连、心跳检测等功能,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

跳转javascript + vue2 WebSocket接收后台实时消息推送 加入心跳包机制
代码(可直接使用)
/* eslint-disable @typescript-eslint/no-unused-vars */
import path from '_api/axios/addressConfig'

import { getStore } from '@/tools/session'

interface OnMessageIter {
  (event: MessageEvent):any
}
interface HeartbeatKey {
  [key:string]:any
}
interface HeartbeatIter extends HeartbeatKey {
  detectionTimer:number
  timeoutTimer:number
  reconnectTimer:number
  sendTimer:number
  isConnected:boolean
  stopReconnect:boolean
  clearTimer: (key:string) => void
  start: (instance:any) => void
  reconnect: (instance:any) => void
  resetHeart: (instance:any) => void
  sendMsg: (instance:any) => void
}
interface WebSocketIter {
  instance:WebSocket | null
  open:(this:WebSocket, event: Event) => any
  close:(this: WebSocket, event: CloseEvent) => any
  error:(this: WebSocket, event: Event) => any
  init:(message:OnMessageIter, url?:string) => void
  sendToken:() => boolean
  closeConnection: () => void
  heartbeat:HeartbeatIter
}
// 保存init入参的fn 在心跳机制中使用
let durableMessageFn:OnMessageIter | null = null

const middlewareSocket:WebSocketIter = {
  instance: null,
  open: function (this:WebSocket, event: Event) {
    console.log('webSocket连接成功 ...')
    middlewareSocket.sendToken()
    middlewareSocket.heartbeat.start(middlewareSocket)
    middlewareSocket.heartbeat.sendMsg(middlewareSocket)
  },
  close: function (this: WebSocket, event: CloseEvent) {
    console.log('webSocket 断开: ' + event.code + ' ' + event.reason + ' ' + event.wasClean)
    middlewareSocket.heartbeat.reconnect(middlewareSocket)
  },
  error: function (this: WebSocket, event: Event) {
    console.log('连接错误', event)
    middlewareSocket.heartbeat.reconnect(middlewareSocket)
  },
  init: function (message, url = `ws://${path.wsUrl}/ws`) {
    if (this.instance?.readyState === 1) {
      console.warn('已存在连接')
      return
    }
    durableMessageFn = message
    this.instance = new WebSocket(url)
    this.instance.onmessage = function (this:WebSocket, event:MessageEvent) {
      console.log(event, '数据')
      middlewareSocket.heartbeat.resetHeart(middlewareSocket)
      message(event)
    }
    this.instance.onopen = this.open
    this.instance.onclose = this.close
    this.instance.onerror = this.error
  },
  sendToken: function ():boolean {
    const token:string | null = getStore('token')
    if (this.instance?.readyState === 1 && token) {
      this.instance?.send(`token:"${token}`)
      return true
    }
    return false
  },
  closeConnection: function () {
    this.instance?.close()
  },
  heartbeat: {
    detectionTimer: 0,
    timeoutTimer: 0,
    reconnectTimer: 0,
    sendTimer: 0,
    isConnected: false,
    stopReconnect: false,
    clearTimer: function (key:string) {
      if (this[key] !== 0) {
        clearTimeout(this[key])
        this[key] = 0
      }
    },
    start: function (instance:WebSocketIter) {
      this.clearTimer('detectionTimer')
      this.clearTimer('timeoutTimer')
      this.detectionTimer = setTimeout(() => {
        this.isConnected = instance.sendToken()
        if (!this.isConnected) {
          // 重新连接
          this.reconnect(instance)
          this.timeoutTimer = setTimeout(() => {
            console.warn('websocket重连超时')
            instance.closeConnection()
          }, 30 * 1000)
        }
      }, 5 * 1000)
    },
    reconnect: function (instance:WebSocketIter) {
      if (this.stopReconnect) {
        return
      }
      this.stopReconnect = true
      instance.closeConnection()
      console.warn('尝试重新连接websocket')
      this.clearTimer('reconnectTimer')
      this.reconnectTimer = setTimeout(() => {
        instance.init(durableMessageFn as OnMessageIter)
        this.stopReconnect = false
      }, 20 * 1000)
    },
    resetHeart: function (instance:WebSocketIter) {
      this.clearTimer('detectionTimer')
      this.clearTimer('timeoutTimer')
      this.start(instance)
    },
    // 配合服务器做心跳机制
    sendMsg: function (instance:WebSocketIter) {
      clearInterval(this.sendTimer)
      this.sendTimer = setInterval(() => {
        if (!(instance.sendToken())) {
          this.reconnect(instance)
          clearInterval(this.sendTimer)
        }
      }, 10 * 1000)
    }
  }
}

export default middlewareSocket

use

middlewareSocket.init(function (event:MessageEvent) {
  console.log(event)
  console.log('收到服务器数据: ' + event.data)
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值