Skip to content

WebSocket连接管理

本文档引用的文件

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构概览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能与异常处理
  8. 故障排查指南
  9. 结论

简介

本文档详细阐述了基于WebSocket的实时通信系统的设计与实现,重点涵盖连接建立、认证机制、生命周期管理、心跳检测、异常重连及连接池管理。系统采用服务端与客户端协同架构,服务端通过websocket.router.ts处理连接请求,利用websocket.dao.ts管理连接状态,常量定义在websocket.constants.ts中。前端通过pc/src/compositions/websocket.tsuni/src/compositions/websocket.ts实现连接初始化与组合式API集成。文档将深入分析认证流程、消息发布/订阅机制及网络异常处理策略。

项目结构

WebSocket功能模块分布在服务端与客户端两个主要目录中。服务端逻辑位于deno/lib/websocket/目录下,包含路由、数据访问对象(DAO)和常量定义。客户端逻辑分别位于pc/src/compositions/(Web端)和uni/src/compositions/(UniApp端),提供统一的API接口。

图示来源

核心组件

系统核心由三个服务端文件和两个客户端文件构成。websocket.constants.ts定义了全局状态存储的Map结构,websocket.dao.ts封装了消息发布与订阅的业务逻辑,websocket.router.ts负责处理WebSocket握手与消息分发。客户端文件则实现了连接管理、自动重连和组合式API。

组件来源

架构概览

系统采用发布/订阅(Pub/Sub)模式,客户端通过唯一clientId连接到服务端。服务端维护三个核心映射关系:socketMap(客户端ID到WebSocket实例列表)、clientIdTopicsMap(客户端ID到订阅主题列表)和callbacksMap(主题到回调函数列表)。消息通过action字段区分操作类型(subscribe, publish, unSubscribe)。

图示来源

详细组件分析

服务端组件分析

websocket.constants.ts

该文件定义了三个全局共享的Map对象,用于存储运行时状态。

图示来源

websocket.dao.ts

该文件提供了对websocket.constants.ts中Map对象的操作接口。

功能分析:

  • subscribe: 为指定主题注册回调函数。
  • publish: 向所有订阅了该主题的客户端广播消息,并触发本地回调。
  • unSubscribe: 从指定主题移除回调函数或取消整个主题订阅。
  • unSubscribes: 批量取消多个主题的订阅。
  • closeClient: 清除所有订阅(目前未被调用)。

图示来源

websocket.router.ts

这是WebSocket的入口点,处理连接升级、认证和消息分发。

关键流程:

  1. 连接认证:检查URL参数中的pwdclientId,使用硬编码密码0YSCBr1QQSOpOfi6GgH34A
  2. 连接建立onopen事件将新连接加入socketMap,并关闭该clientId的旧连接。
  3. 消息处理onmessage根据action字段分发消息。
    • ping: 回复pong,用于心跳检测。
    • subscribe: 更新clientIdTopicsMap
    • publish: 调用websocket.dao.tspublish函数。
    • unSubscribe: 从clientIdTopicsMap中移除主题。

异常处理:

  • oncloseonerror事件会清理socketMapclientIdTopicsMap中的对应条目。
  • 使用try-catch捕获并记录错误。

组件来源

客户端组件分析

pc/src/compositions/websocket.ts

Web端的WebSocket管理模块,使用标准WebSocket API。

核心特性:

  • 连接管理connect()函数负责创建和初始化WebSocket连接。
  • 自动重连reConnect()函数在连接断开后按指数退避策略重试。
  • 心跳机制socketPing()每60秒发送一次ping消息。
  • 订阅管理topicCallbackMap在前端维护订阅关系,useSubscribe提供Vue组合式API支持。
  • 连接复用与延迟关闭closeSocketTimeout在无订阅后10分钟关闭连接,避免频繁重连。

组件来源

uni/src/compositions/websocket.ts

UniApp端的WebSocket管理模块,使用uni.connectSocket API。

与Web端的差异:

  • 使用uni.connectSocket而非原生WebSocket
  • 消息发送需通过socket.send({ data: ... })对象形式。
  • 错误处理中socket?.close({})调用带空对象参数。
  • 其余逻辑(重连、心跳、订阅管理)与Web端保持一致。

组件来源

依赖关系分析

系统依赖关系清晰,服务端内部router依赖daoconstants,客户端依赖服务端的API。客户端之间通过服务端进行间接通信。

图示来源

性能与异常处理

性能考量

  • 内存使用socketMapclientIdTopicsMap会随客户端数量线性增长,需监控内存。
  • 消息广播publish操作的时间复杂度为O(N*M),N为订阅客户端数,M为平均连接数。在高并发场景下可能成为瓶颈。
  • 连接复用:前端的延迟关闭机制有效减少了连接建立的开销。

异常处理策略

  • 网络中断:客户端oncloseonerror触发reConnect,实现自动重连。
  • 服务器重启:客户端在重连时会重新发送subscribe消息,恢复订阅状态。
  • 无效连接:服务端在发送消息前检查readyState,并清理无效连接。
  • 认证失败:服务端直接返回HTTP错误码,客户端需处理连接失败。

故障排查指南

  • 连接失败:检查URL中的pwd是否正确,clientId是否缺失。
  • 消息收不到:确认subscribe消息已成功发送,检查clientIdTopicsMap中是否存在对应条目。
  • 频繁重连:检查网络状况,或服务端日志是否有onerror记录。
  • 内存泄漏:检查socketMapclientIdTopicsMap是否在连接关闭后被正确清理。目前closeClient函数未被调用,unSubscribe仅在无回调时清理callbacksMap,可能存在内存泄漏风险。

组件来源

结论

该WebSocket系统实现了完整的连接管理、认证、发布/订阅和异常恢复机制。架构清晰,前后端职责分明。主要优势在于自动重连和连接复用机制。潜在改进点包括:将硬编码密码移至配置文件、优化publish的广播性能、实现更完善的连接池清理策略,以及增加服务端主动推送连接状态的功能。