封装WebSocket

一个基于原生 WebSocket 的封装库,实现了自动重连、心跳检测等功能,用于在前端应用中稳定地与后端 WebSocket 服务通信。下面从设计思路、关键功能等方面进行详细分析:

设计思路

这个封装库采用单例模式设计,全局维护一个 WebSocket 实例,通过状态管理和事件监听实现高可用的通信连接。主要特点包括:

集成了心跳机制检测连接状态

实现了自动重连逻辑

提供了简洁的 API 接口

支持自定义配置参数(如重连次数、心跳间隔等)

关键功能分析

  1. 初始化与连接管理
javascript 复制代码
init: (receiveMessage: Function | null) => {
  // 检查浏览器支持
  if (!('WebSocket' in window)) {
    console.error('浏览器不支持WebSocket')
    return null
  }

  // 构建连接URL,携带用户认证信息
  socket.connectURL = `ws://${location.host}/api/websocket/connect?Authorization=${
    useUserStore().token
  }`

  // 创建WebSocket实例并绑定事件
  socket.websocket = socket.websocket || new WebSocket(socket.connectURL)
  
  // 绑定事件处理函数...
}

这部分代码完成了:

浏览器兼容性检查

连接 URL 构建,从用户状态中获取认证 token

WebSocket 实例的创建和事件绑定

  1. 心跳检测机制
javascript 复制代码
heartbeat: () => {
  if (socket.heartbeatTimer) {
    clearInterval(socket.heartbeatTimer)
  }
  socket.heartbeatTimer = setInterval(() => {
    if (socket.heartbeatCurrent > socket.heartbeatCount) {
      clearInterval(socket.heartbeatTimer)
      socket.reconnect()
    } else {
      socket.send('ping')
      socket.heartbeatCurrent++
    }
  }, socket.heartbeatInterval)
}

心跳机制的工作流程:

定期发送 "ping" 消息

接收到 "pong" 响应时重置计数器

连续多次未收到响应时触发重连

使用指数退避算法避免频繁重连

  1. 自动重连实现
javascript 复制代码
reconnect: () => {
  if (socket.isReconnect) {
    socket.reconnectTimer = setTimeout(() => {
      if (socket.reconnectCurrent >= socket.reconnectCount) {
        socket.isReconnect = false
        return
      }
      
      socket.reconnectCurrent++
      console.log('websocket正在重新连接')
      socket.init(null)
    }, socket.reconnectInterval)
  }
}

重连机制的关键点:

限制最大重连次数,避免无限重试

使用定时器控制重连间隔

保持重连状态的跟踪

  1. 消息处理
javascript 复制代码
websocket.onmessage = (e: MessageEvent) => {
  const { data } = e

  // 心跳检测
  if (data === 'pong') {
    socket.heartbeatCurrent = 0
    return
  }

  if (receiveMessage) {
    receiveMessage(data)
  }
}

消息处理逻辑:

区分心跳响应和业务消息

通过回调函数将消息传递给上层应用

相关推荐
jay神24 分钟前
基于 YOLOv8 的轴承缺陷检测(Web 版)
前端·人工智能·yolo
jay神32 分钟前
基于 YOLOv8 的森林火灾检测系统(Web 版)
前端·yolo
code2cat36 分钟前
HTML基础篇之第一张网页:从index.html到浏览器里的任务清单
前端·html
miss1 小时前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
AiMan2 小时前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真2 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment2 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan2 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么2 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模
QXWZ_IA3 小时前
定位数据怎么推给 IoT 平台?消息协议选型与接入准备
网络·人工智能·物联网·安全