# WebSocket服务

<cite>
**本文引用的文件**
- [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)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本文件面向AI有声书生成平台的WebSocket服务，系统性阐述实时通信服务的实现架构与使用方式，覆盖连接管理、消息路由、断线重连、心跳检测、连接池管理、消息广播、私信发送、房间管理等能力。同时提供客户端WebSocket连接的集成示例、消息格式定义、事件处理与状态同步方案，并结合播放器状态同步、实时通知、多端协作等场景说明WebSocket的应用价值。

## 项目结构
WebSocket服务在后端以独立服务模块形式提供，前端通过统一的WebSocket管理器封装连接、订阅、重连与消息处理逻辑。整体结构如下：

```mermaid
graph TB
subgraph "后端服务"
APP["应用入口<br/>app.ts"]
WS["WebSocket服务<br/>websocket.service.ts"]
PLAYER_CTRL["播放器控制器<br/>player.controller.ts"]
PLAYER_SVC["播放器服务<br/>player.service.ts"]
end
subgraph "前端应用"
WS_CLIENT["WebSocket管理器<br/>websocket.ts"]
AUDIO_STORE["音频状态存储<br/>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实现消息持久化与离线推送。

[本节为概念性扩展，无需列出章节来源]