# WebSocket服务
**本文引用的文件**
- [websocket.service.ts](file://server/src/services/websocket.service.ts)
- [websocket.ts](file://my-uniapp-vue3/src/utils/websocket.ts)
- [app.ts](file://server/src/app.ts)
- [player.controller.ts](file://server/src/modules/player/player.controller.ts)
- [player.service.ts](file://server/src/modules/player/player.service.ts)
- [audio.ts](file://my-uniapp-vue3/src/store/audio.ts)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向AI有声书生成平台的WebSocket服务,系统性阐述实时通信服务的实现架构与使用方式,覆盖连接管理、消息路由、断线重连、心跳检测、连接池管理、消息广播、私信发送、房间管理等能力。同时提供客户端WebSocket连接的集成示例、消息格式定义、事件处理与状态同步方案,并结合播放器状态同步、实时通知、多端协作等场景说明WebSocket的应用价值。
## 项目结构
WebSocket服务在后端以独立服务模块形式提供,前端通过统一的WebSocket管理器封装连接、订阅、重连与消息处理逻辑。整体结构如下:
```mermaid
graph TB
subgraph "后端服务"
APP["应用入口
app.ts"]
WS["WebSocket服务
websocket.service.ts"]
PLAYER_CTRL["播放器控制器
player.controller.ts"]
PLAYER_SVC["播放器服务
player.service.ts"]
end
subgraph "前端应用"
WS_CLIENT["WebSocket管理器
websocket.ts"]
AUDIO_STORE["音频状态存储
audio.ts"]
end
APP --> WS
WS --> PLAYER_CTRL
WS --> PLAYER_SVC
WS_CLIENT --> WS
AUDIO_STORE --> WS_CLIENT
```
**图表来源**
- [app.ts:133-167](file://server/src/app.ts#L133-L167)
- [websocket.service.ts:102-133](file://server/src/services/websocket.service.ts#L102-L133)
- [websocket.ts:26-82](file://my-uniapp-vue3/src/utils/websocket.ts#L26-L82)
- [player.controller.ts:14-88](file://server/src/modules/player/player.controller.ts#L14-L88)
- [player.service.ts:10-81](file://server/src/modules/player/player.service.ts#L10-L81)
- [audio.ts:112-141](file://my-uniapp-vue3/src/store/audio.ts#L112-L141)
**章节来源**
- [app.ts:133-167](file://server/src/app.ts#L133-L167)
- [websocket.service.ts:102-133](file://server/src/services/websocket.service.ts#L102-L133)
- [websocket.ts:26-82](file://my-uniapp-vue3/src/utils/websocket.ts#L26-L82)
## 核心组件
- 后端WebSocket服务:负责升级HTTP连接为WebSocket、客户端连接管理、消息广播与事件推送。
- 前端WebSocket管理器:负责连接建立、消息编解码、事件订阅/退订、断线重连与重订阅。
- 应用入口:在启动时初始化WebSocket服务并挂载至HTTP服务器。
- 播放器模块:提供播放进度的增删改查接口,为WebSocket状态同步提供数据基础。
**章节来源**
- [websocket.service.ts:16-47](file://server/src/services/websocket.service.ts#L16-L47)
- [websocket.ts:15-196](file://my-uniapp-vue3/src/utils/websocket.ts#L15-L196)
- [app.ts:156-157](file://server/src/app.ts#L156-L157)
- [player.controller.ts:14-88](file://server/src/modules/player/player.controller.ts#L14-L88)
## 架构总览
WebSocket服务采用“升级+广播”模式:
- 服务端监听HTTP升级事件,将符合条件的请求升级为WebSocket连接。
- 客户端通过查询参数携带clientId接入,服务端维护clientId到WebSocket实例的映射。
- 服务端提供广播与定向推送能力,前端通过事件驱动进行状态同步。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Server as "HTTP服务器"
participant WSS as "WebSocket服务"
participant Clients as "连接池(Map)"
Client->>Server : "HTTP Upgrade 请求 /ws?clientId=..."
Server->>WSS : "交由WebSocket处理"
WSS->>Clients : "addClient(clientId, ws)"
WSS-->>Client : "connected 事件"
Note over Client,WSS : "客户端可发送订阅/取消订阅消息"
```
**图表来源**
- [websocket.service.ts:104-129](file://server/src/services/websocket.service.ts#L104-L129)
- [websocket.ts:36-82](file://my-uniapp-vue3/src/utils/websocket.ts#L36-L82)
## 详细组件分析
### 后端WebSocket服务(server/src/services/websocket.service.ts)
- 连接管理
- 客户端注册:addClient(clientId, ws)将clientId与WebSocket实例绑定。
- 客户端移除:removeClient(clientId)在连接关闭或错误时清理。
- 客户端查询:sendToClient(clientId, event, data)向指定客户端发送消息。
- 广播与事件推送
- broadcast(event, data)对所有已连接且处于OPEN状态的客户端广播消息。
- pushAudioGenerationComplete / pushVideoGenerationComplete / pushBatchGenerationProgress 提供预置事件推送。
- 服务初始化
- initWebSocket(server)监听HTTP upgrade事件,校验路径为/ws,升级后写入clientId并发送connected事件。
```mermaid
classDiagram
class WebSocketService {
+addClient(clientId, ws) void
+removeClient(clientId) void
+sendToClient(clientId, event, data) bool
+broadcast(event, data) void
+pushAudioGenerationComplete(bookId, chapterId, status) void
+pushVideoGenerationComplete(bookId, chapterId, status) void
+pushBatchGenerationProgress(taskId, step, progress) void
+initWebSocket(server) void
}
class ClientsMap {
+Map~string, WebSocket~ clients
}
WebSocketService --> ClientsMap : "维护连接池"
```
**图表来源**
- [websocket.service.ts:16-95](file://server/src/services/websocket.service.ts#L16-L95)
**章节来源**
- [websocket.service.ts:16-95](file://server/src/services/websocket.service.ts#L16-L95)
- [websocket.service.ts:102-133](file://server/src/services/websocket.service.ts#L102-L133)
### 前端WebSocket管理器(my-uniapp-vue3/src/utils/websocket.ts)
- 连接生命周期
- connect(url?):基于全局基础地址构造ws/wss协议,发起uni.connectSocket连接;监听onOpen/onMessage/onError/onClose。
- send(event, data):序列化消息并发送;未连接时警告。
- close():主动关闭并阻止后续重连。
- 事件订阅与重连
- on(event, handler):注册事件处理器并记录订阅;若已连接则向服务端发送_subcribe事件。
- off(event, handler):移除处理器;当事件无处理器时从订阅集合移除。
- handleReconnect():指数退避重连(最多3次),重连后自动resubscribe。
- 消息格式
- 服务端与客户端均使用统一消息体:{ event: string, data: any }。
```mermaid
flowchart TD
Start(["开始"]) --> Connect["发起连接"]
Connect --> Open{"连接成功?"}
Open --> |否| Fail["失败回调/等待重连"]
Open --> |是| Sub["_subscribe 订阅事件"]
Sub --> Listen["监听消息"]
Listen --> Msg["解析消息并触发事件"]
Msg --> Close{"连接断开?"}
Close --> |是| Reconnect["重连流程"]
Close --> |否| Listen
Reconnect --> Max{"超过最大重连次数?"}
Max --> |是| Stop["停止重连"]
Max --> |否| Connect
```
**图表来源**
- [websocket.ts:26-82](file://my-uniapp-vue3/src/utils/websocket.ts#L26-L82)
- [websocket.ts:163-190](file://my-uniapp-vue3/src/utils/websocket.ts#L163-L190)
**章节来源**
- [websocket.ts:15-196](file://my-uniapp-vue3/src/utils/websocket.ts#L15-L196)
### 应用入口与服务挂载(server/src/app.ts)
- 在启动阶段调用initWebSocket(server),将WebSocket服务挂载到HTTP服务器。
- 服务启动后,WebSocket监听/ws路径,仅允许该路径的升级请求。
```mermaid
sequenceDiagram
participant Boot as "启动流程"
participant App as "Koa应用"
participant Server as "HTTP服务器"
participant WS as "WebSocket服务"
Boot->>App : "创建Koa应用"
Boot->>Server : "创建HTTP服务器"
Boot->>WS : "initWebSocket(server)"
WS-->>Server : "注册upgrade事件处理"
Boot-->>Server : "监听端口"
```
**图表来源**
- [app.ts:156-157](file://server/src/app.ts#L156-L157)
- [websocket.service.ts:102-133](file://server/src/services/websocket.service.ts#L102-L133)
**章节来源**
- [app.ts:156-157](file://server/src/app.ts#L156-L157)
### 播放器状态同步(player.controller.ts 与 player.service.ts)
- 后端提供播放进度的增删改查接口,前端通过这些接口获取/更新播放状态,配合WebSocket实现跨端状态同步。
- 典型流程:前端播放器状态变化时,通过接口更新后端状态;后端可将播放进度变更通过WebSocket广播或定向推送至其他设备。
```mermaid
sequenceDiagram
participant FE as "前端播放器"
participant API as "播放器API"
participant DB as "数据库"
participant WS as "WebSocket服务"
FE->>API : "保存播放进度"
API->>DB : "upsert/insert/update"
DB-->>API : "返回最新状态"
API-->>FE : "返回结果"
Note over WS,DB : "可选:服务端将状态变更通过WS广播/定向推送"
```
**图表来源**
- [player.controller.ts:14-88](file://server/src/modules/player/player.controller.ts#L14-L88)
- [player.service.ts:10-81](file://server/src/modules/player/player.service.ts#L10-L81)
**章节来源**
- [player.controller.ts:14-88](file://server/src/modules/player/player.controller.ts#L14-L88)
- [player.service.ts:10-81](file://server/src/modules/player/player.service.ts#L10-L81)
## 依赖关系分析
- 后端WebSocket服务依赖ws库与Node内置http.Server。
- 应用入口在启动时导入并初始化WebSocket服务。
- 前端WebSocket管理器依赖uni原生WebSocket API(H5/小程序)。
```mermaid
graph LR
Node["Node.js 环境"] --> HTTP["http.Server"]
HTTP --> WS["ws 库"]
APP["app.ts"] --> WS_SRV["websocket.service.ts"]
WS_SRV --> Clients["连接池 Map"]
FE_WS["websocket.ts"] --> UniAPI["uni.connectSocket"]
```
**图表来源**
- [websocket.service.ts:6-9](file://server/src/services/websocket.service.ts#L6-L9)
- [app.ts:55](file://server/src/app.ts#L55)
- [websocket.ts:36](file://my-uniapp-vue3/src/utils/websocket.ts#L36)
**章节来源**
- [websocket.service.ts:6-9](file://server/src/services/websocket.service.ts#L6-L9)
- [app.ts:55](file://server/src/app.ts#L55)
- [websocket.ts:36](file://my-uniapp-vue3/src/utils/websocket.ts#L36)
## 性能考虑
- 连接池管理
- 使用Map维护clientId到WebSocket实例的映射,便于定向推送与清理。
- 广播时仅对readyState为OPEN的连接发送,避免异常连接导致的错误。
- 事件推送
- 预置事件如音频/视频生成完成、批量生成进度,减少业务侧重复实现。
- 断线重连
- 前端支持最大重连次数与延迟退避策略,降低网络抖动影响。
- 建议
- 对高频事件采用去抖/节流策略,避免消息风暴。
- 对大体量广播场景,考虑按房间/用户分片推送。
[本节为通用指导,无需列出章节来源]
## 故障排查指南
- 连接失败
- 检查服务端是否正确挂载WebSocket(/ws路径)。
- 检查客户端URL是否为ws/wss协议,域名与端口是否正确。
- 无法接收消息
- 确认前端已订阅对应事件(on事件)。
- 检查服务端是否正确发送消息(sendToClient/broadcast)。
- 断线频繁
- 查看前端重连日志与退避策略。
- 检查网络稳定性与代理设置。
- 服务端错误
- 查看服务端控制台错误日志,关注客户端错误与关闭事件处理。
**章节来源**
- [websocket.service.ts:118-125](file://server/src/services/websocket.service.ts#L118-L125)
- [websocket.ts:66-76](file://my-uniapp-vue3/src/utils/websocket.ts#L66-L76)
## 结论
WebSocket服务为AI有声书平台提供了低延迟、双向通信的基础设施,支撑生成任务状态推送、播放器状态同步与多端协作。通过清晰的连接管理、事件订阅与断线重连机制,以及与播放器模块的协同,平台可在复杂场景下保持稳定与一致的用户体验。
[本节为总结性内容,无需列出章节来源]
## 附录
### 客户端集成示例(步骤说明)
- 建立持久连接
- 使用connectAndSubscribe(events, handlers)一次性完成连接与订阅。
- 或使用wsManager.connect()后逐个wsManager.on(event, handler)订阅。
- 处理消息推送
- 在订阅处理器中解析data并更新本地状态。
- 对于播放器状态,结合audio.ts的状态存储进行UI联动。
- 播放进度同步
- 前端播放器状态变化时,调用播放器API保存进度。
- 后端可将进度变更通过WebSocket广播至其他设备。
```mermaid
sequenceDiagram
participant Page as "播放器页面"
participant Store as "audio.ts"
participant WS as "wsManager"
participant API as "播放器API"
participant DB as "数据库"
Page->>Store : "播放/暂停/跳转"
Store->>API : "保存播放进度"
API->>DB : "upsert"
DB-->>API : "返回最新进度"
API-->>Page : "返回结果"
Note over WS,DB : "可选:服务端将进度变更通过WS推送"
```
**图表来源**
- [audio.ts:112-141](file://my-uniapp-vue3/src/store/audio.ts#L112-L141)
- [player.controller.ts:32-53](file://server/src/modules/player/player.controller.ts#L32-L53)
- [websocket.ts:101-120](file://my-uniapp-vue3/src/utils/websocket.ts#L101-L120)
### 消息格式定义
- 通用消息体
- event: string(事件名称)
- data: any(事件数据)
- 预置事件
- connected:连接成功,data包含clientId。
- audio_generation_complete:音频生成完成,data包含bookId、chapterId、status。
- video_generation_complete:视频生成完成,data包含bookId、chapterId、status。
- batch_generation_progress:批量生成进度,data包含taskId、step、progress。
**章节来源**
- [websocket.ts:9-12](file://my-uniapp-vue3/src/utils/websocket.ts#L9-L12)
- [websocket.service.ts:70-95](file://server/src/services/websocket.service.ts#L70-L95)
### 房间管理与私信发送(扩展建议)
- 房间管理
- 基于clientId分组,维护房间ID到成员列表的映射。
- 提供房间内广播与房间定向推送接口。
- 私信发送
- 基于sendToClient实现一对一消息推送。
- 可结合用户会话ID实现消息持久化与离线推送。
[本节为概念性扩展,无需列出章节来源]