# JRSoft Subway WebSocket 协议规范 v1.0

## 目录
1. [概述](#概述)
2. [设计原则](#设计原则)
3. [消息格式](#消息格式)
4. [连接生命周期](#连接生命周期)
5. [消息类型详解](#消息类型详解)
6. [错误处理](#错误处理)
7. [安全性](#安全性)
8. [性能优化](#性能优化)
9. [版本管理](#版本管理)
10. [命令系统架构](#命令系统架构)
11. [程序上传流程示例](#程序上传流程示例)

## 概述

JRSoft Subway 使用 WebSocket 协议进行实时双向通信。Gateway 作为中心节点，连接和管理所有客户端：

```
             WebSocket              WebSocket
┌─────────┐ ──────────▶ ┌─────────┐ ──────────▶ ┌─────────┐
│ Device  │             │  Edge   │             │         │
└─────────┘             └─────────┘             │         │
                                                │ Gateway │ ◀────── Backend
┌─────────┐ ──────────▶ ┌─────────┐ ──────────▶ │         │
│ Device  │  WebSocket  │  Edge   │  WebSocket  │         │
└─────────┘             └─────────┘             └─────────┘
```

### 客户端类型

1. **Device** - 物理设备（地铁设备、控制器等），通过 WebSocket 连接到 Edge
2. **Backend** - 后端服务（WebAPI、管理系统），直接连接 Gateway
3. **Edge** - 边缘计算节点，作为本地 Gateway，一个 Edge 可以管理多个设备并连接到中央 Gateway
4. **Gateway** - 中心路由网关，管理所有客户端连接和消息路由

### Edge 设备管理模式

一个 Edge 节点可以管理一套或多套隧道媒体广告播放系统的设备端：

```
┌─────────────────────────────────────────┐
│                Edge (edge-001)               │
│                                                 │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐ │
│  │ 设备端    │  │ 设备端      │  │ 设备端      │ │
│  │ (td-01)  │  │ (td-01)  │  │ (td-01)│ │
│  └──────────┘  └──────────┘  └──────────┘ │
│                                                 │
└─────────────────────────────────────────┘
```

## 设计原则

1. **简单性优先** - 基础功能使用最简单的消息格式
2. **渐进增强** - 高级功能通过可选字段实现
3. **统一标准** - 所有组件使用相同的协议版本
4. **明确语义** - 每个消息类型有清晰的用途
5. **故障隔离** - 单个客户端故障不影响其他客户端

## 长时间运行操作的设计思路

### 统一的进度上报机制

对于需要较长时间执行的操作，协议提供了统一的进度上报机制：

1. **Batch类型、Complex类型命令**（如健康检查、状态监控）
   - 使用标准的 `command` 消息发起
   - 执行过程中通过 `progress_update` 报告各阶段结果
   - 最终通过 `command_response` 标志执行结束
   - 适用于：需要多步骤执行并返回中间结果的命令

2. **程序上传流程**
   - 使用专门的 `program` 消息发起（区别于普通命令）
   - 通过 `progress_update` 报告各阶段进度（下载、解压、预处理、创建帧、上传、统计）
   - 携带 `context` 确保每个进度更新可追溯
   - 最终通过简化的 `program_response` 标志流程结束
   - 适用于：文件传输类的长时间操作

### 进度更新消息的设计

`progress_update` 消息设计为通用的进度报告机制：
- **status** - 表示当前状态（pending、in_progress、paused、completed、failed、cancelled）
- **phase** - 表示当前所处阶段
- **progress** - 百分比进度（0-100）
- **sourceType** - 区分是设备命令结果还是系统消息
- **command** - 记录相关的设备操作（可选）
- **report** - 结构化日志信息，包含级别、消息、代码和附加数据
- **context** - 程序上传时的上下文信息（可选）

### 流程结束标志

所有长时间运行的操作都有明确的结束标志：
- Batch命令、Complex命令：`command_response` 消息
- 程序上传：`program_response` 消息
- 结束消息包含最终状态（completed、failed、timeout、cancelled）

## 消息格式

### 基础消息结构

所有消息都基于 JSON 格式，包含以下基础字段：

```typescript
interface BaseMessage {
  type: MessageType;      // 必需：消息类型（枚举）
  timestamp: string;      // 必需：ISO 8601 时间戳
  version: string;        // 必需：协议版本 "1.0"
}
```

### 消息分类

```
消息
├── 连接管理
│   ├── register / register_ack
│   ├── unregister / unregister_ack
│   └── heartbeat / heartbeat_ack
├── 命令执行
│   ├── command / command_response
│   └── progress_update （支持阶段、状态、日志、设备命令）
├── 程序管理
│   ├── program （程序上传请求）
│   └── program_response （程序上传最终响应）
└── 系统消息
    └── error
```

## 连接生命周期

### 1. 连接建立

```sequence
Client->Gateway: WebSocket Connect
Gateway->Client: Connection Established
```

### 2. 客户端注册

```sequence
Client->Gateway: register
Gateway->Client: register_ack
```

**Backend 注册：**
```json
{
  "type": "REGISTER",
  "clientId": "backend-server",
  "clientType": "BACKEND",
  "clientInfo": {
    "version": "1.0.0",
    "platform": "nodejs",
    "capabilities": ["command", "program", "Ubatch"]
  },
  "timestamp": "2024-01-20T10:00:00Z",
  "version": "1.0"
}
```

**Edge 注册场景：**

Edge 节点有两种注册场景：

**场景1：Edge 先启动，设备端已连接，然后 Gateway 重启**
```
1. Edge 与多个设备端保持 WebSocket 连接
2. Gateway 重启或网络恢复
3. Edge 检测到 Gateway 可用，连接并注册自己
4. Edge 为每个已连接的设备端发送注册消息（包含 Edge 信息）
```

**场景2：Gateway 在线，Edge 启动后注册**
```
1. Gateway 已在线运行
2. Edge 启动并连接到 Gateway
3. Edge 先注册自己
4. 设备端连接到 Edge 后，Edge 为其发送注册消息
```

**Edge 自身注册消息：**
```json
{
  "type": "REGISTER",
  "clientId": "edge-001",
  "clientType": "EDGE",
  "clientInfo": {
    "version": "1.0.0",
    "platform": "edge-proxy",
    "capabilities": ["device_proxy", "batch_command", "status_report"]
  },
  "timestamp": "2024-01-20T10:00:00Z",
  "version": "1.0"
}
```

**Edge 为设备端注册（包含 Edge 信息）：**
```json
{
  "type": "REGISTER",
  "clientId": "td-01",  // 设备端 ID
  "clientType": "DEVICE",
  "edgeInfo": {  // Edge 信息
    "edgeId": "edge-001",
    "edgeVersion": "1.0.0",
    "connectionTime": "2024-01-20T09:59:00Z"
  },
  "clientInfo": {
    "version": "1.0.0",
    "deviceType": "media_player",
    "capabilities": ["play", "stop", "status_report"]
  },
  "timestamp": "2024-01-20T10:00:01Z",
  "version": "1.0"
}
```

**注册确认：**
```json
{
  "type": "REGISTER_ACK",
  "clientId": "device001",
  "success": true,
  "sessionId": "sess-123456",  // 可选
  "timestamp": "2024-01-20T10:00:01Z"
}
```

### 3. 心跳维持

```sequence
Client->Gateway: heartbeat
Gateway->Client: heartbeat_ack
```

心跳间隔：30秒
超时断开：90秒（3个心跳周期）

**心跳消息：**
```json
{
  "type": "HEARTBEAT",
  "clientId": "device001",
  "sequence": 123,  // 可选：序列号
  "timestamp": "2024-01-20T10:00:30Z",
  "version": "1.0"
}
```

**心跳确认：**
```json
{
  "type": "HEARTBEAT_ACK",
  "clientId": "device001",
  "sequence": 123,  // 可选：与请求相同的序列号
  "timestamp": "2024-01-20T10:00:30Z",
  "version": "1.0"
}
```

### 4. 连接断开

```sequence
Client->Gateway: unregister
Gateway->Client: unregister_ack
Client->Gateway: Close Connection
```

**注销消息：**
```json
{
  "type": "UNREGISTER",
  "clientId": "device001",
  "reason": "shutdown",  // 可选：shutdown, maintenance, error
  "timestamp": "2024-01-20T11:00:00Z",
  "version": "1.0"
}
```

**注销确认：**
```json
{
  "type": "UNREGISTER_ACK",
  "clientId": "device001",
  "success": true,
  "timestamp": "2024-01-20T11:00:00Z",
  "version": "1.0"
}
```

## 消息类型详解

### 1. 命令执行流程

Gateway 作为命令路由中心，支持多种命令模式。命令支持两种类型定义方式：

1. **强类型命令**：基于 C# 模型生成的类型安全命令
2. **通用命令**：灵活的键值对参数命令

强类型命令示例：
```typescript
// 使用强类型工厂创建命令
import { createLedSwitchCommand } from '@jrsoft/subway-protocol';

const command = createLedSwitchCommand(
  'req-123',      // requestRef
  'device-001',   // targetClientId
  1,             // deviceId
  'ON',           // switch: 'ON' | 'OFF'
  'write'         // operationType
);
```

#### a) Simple 类型命令

Simple 类型命令是最基本的命令类型，一次请求对应一次响应。

**命令路由流程：**

```sequence
Backend->Gateway: command  
Gateway->Edge: command
Edge->Device: command
Device->Edge: command_response
Edge->Gateway: command_response
Gateway->Backend: command_response
```

**关键设计：**
- Gateway 作为中央路由器，根据 `targetClientId` 决定路由到哪个 Edge
- 所有设备都通过 Edge 接入（Edge 是设备的接入点）
- Gateway 负责管理多个 Edge 的连接
- Edge 负责管理本地设备的连接
- 全程使用 `command` 消息类型，无需转换
- 通过 `requestRef` 关联请求和响应

**命令请求示例：**

```json
{
  "type": "COMMAND",
  "requestRef": "req-123",
  "targetClientId": "td-01",  // 设备ID
  "command": {
    "commandType": "SIMPLE",
    "commandCode": "SET_COLOR",
    "deviceType": "pillar",
    "deviceId": 1,
    "operationType": "WRITE",
    "parameters": {
      "color": "#FF0000"
    }
  },
  "priority": "HIGH",
  "timeout": 10000,
  "callback": "http://backend/api/callback/req-123",
  "timestamp": "2024-01-20T10:00:00Z",
  "version": "1.0"
}
```

**targetClientId 格式说明：**
- 直接使用设备ID：`"td-01"`、`"td-02"` 等
- Backend 只需指定目标设备ID，无需知道 Edge 节点
- Gateway 维护设备到 Edge 的路由表，自动路由到正确的 Edge
- Edge 接收到命令后，转发给对应的设备

**Simple 命令响应格式：**

Simple 命令的响应遵循请求的反向路径返回：

```json
{
  "type": "COMMAND_RESPONSE",
  "requestRef": "req-123",  // 与请求的 requestRef 相同
  "status": "COMPLETED",    // 命令执行状态
  "result": {
    "deviceType": "pillar",
    "deviceId": 1,
    "commandCode": "SET_COLOR",
    "operationType": "WRITE",
    "data": {
      "previousColor": "#00FF00",
      "currentColor": "#FF0000",
      "executedAt": "2024-01-20T10:00:01Z"
    }
  },
  "executionTime": 150,  // 执行时间（毫秒）
  "timestamp": "2024-01-20T10:00:01Z",
  "version": "1.0"
}
```

**失败响应示例：**
```json
{
  "type": "COMMAND_RESPONSE",
  "requestRef": "req-123",
  "status": "FAILED",
  "result": {
    "deviceType": "pillar",
    "deviceId": 1,
    "commandCode": "SET_COLOR",
    "operationType": "WRITE",
    "data": {
      "Uerror": "Invalid color format",
      "providedColor": "#GGGGGG"
    }
  },
  "report": {
    "level": "ERROR",
    "message": "颜色格式无效",
    "code": "INVALID_COLOR_FORMAT"
  },
  "timestamp": "2024-01-20T10:00:01Z",
  "version": "1.0"
}
```

**响应路由：**
- 设备生成响应后，按原路径返回
- Edge（如果有）转发响应到 Gateway
- Gateway 根据 `requestRef` 路由响应到发起方（Backend）
- 如配置了 `callback`，Gateway 还会通过 HTTP POST 推送响应

#### b) Batch 类型命令（持续响应）

Batch 类型命令是向同一设备端的多个同一类型的子硬件（如编号为1-480的光柱）发送相同命令

```json
{
  "type": "COMMAND",
  "requestRef": "req-123",
  "targetClientId": "td-01",  // 设备ID（批量命令作用于该设备下的多个子硬件）
  "command": {
    "commandType": "BATCH",  // 标识为 batch 类型命令
    "commandCode": "TRAIN_LENGTH",
    "deviceType": "pillar",
    "deviceId": "1-10,30-40,51,52,53,54",  // 子硬件范围：1到10，30到40，以及51,52,53,54;0代表所有同类型设备
    "operationType": "WRITE",
    "parameters": {
      "switch": "ON"  // 必须是 "ON" 或 "OFF"
    }
  },
  "priority": "HIGH",
  "timeout": 10000,
  "callback": "http://backend/api/callback/req-123"
}
```

**Batch 命令执行模式：**

批量命令采用与程序上传相同的执行模式，通过 `progress_update` 报告每个设备的执行状态：

**进度更新示例（每个设备执行后）：**
```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "req-123",
  "status": "IN_PROGRESS",
  "phase": "executing",
  "progress": 25,  // 25% 完成 (6/24 设备)
  "sourceType": "COMMAND",
  "command": {
    "commandType": "SIMPLE",
    "commandCode": "SET_COLOR",
    "deviceType": "pillar",
    "deviceId": 3,
    "operationType": "WRITE",
    "result": {
      "Uerror": "Device not responding"
    }
  },
  "report": {
    "level": "ERROR",
    "message": "设备 3 执行失败",
    "code": "DEVICE_TIMEOUT"
  },
  "timestamp": "2024-01-20T10:00:00Z",
  "version": "1.0"
}
```

**最终响应（所有设备完成后）：**
```json
{
  "type": "COMMAND_RESPONSE",
  "requestRef": "req-123",
  "status": "COMPLETED",
  "result": {
    "deviceType": "pillar",
    "deviceId": "1-10,30-40,51-54",  // 原始批量目标
    "commandCode": "SET_COLOR",
    "operationType": "WRITE",
    "data": {
      "message": "批量命令执行完成",
      "targetCount": 24,
      "successCount": 23,
      "failureCount": 1
    }
  },
  "summary": {
    "total": 24,
    "successful": 23,
    "Ufailed": 1,
    "failedTargets": [3]
  },
  "executionTime": 2500,
  "timestamp": "2024-01-20T10:00:02Z",
  "version": "1.0"
}
```

#### c) Complex 类型命令（持续响应）

Complex 类型命令是发送一个指令后，设备端会持续返回多个响应，直到完成。典型应用：一键检测、监播数据导出、系统日志。

**命令示例：**

```json
{
  "type": "COMMAND",
  "requestRef": "health-check-001",
  "targetClientId": "td-01",
  "command": {
    "commandType": "COMPLEX",
    "commandCode": "HealthCheck",
    "parameters": {
      "switchStatus": true,
      "switchConfigInformation": true,
      "synchronizerStatus": true,
      "pillarStatus": true
    }
  },
  "priority": "NORMAL",
  "timeout": 30000
}
```

**Complex命令设计思路：**
- Complex类型命令用于需要持续响应的场景，如健康检查、监播数据导出、系统日志等
- 设备可以在执行过程中发送多个 `progress_update` 消息报告不同阶段的结果
- 最终必须发送一个 `command_response` 消息表示命令执行结束
- 所有消息通过 `requestRef` 关联到原始命令请求

**设备端持续响应流程：**
```sequence
Backend->Gateway: HealthCheck command
Gateway->Edge: command
Edge->Device: command
Device->Edge: progress_update (检查开关状态)
Edge->Gateway: progress_update
Gateway->Backend: progress_update
Device->Edge: progress_update (读取配置信息)
Edge->Gateway: progress_update
Gateway->Backend: progress_update
Device->Edge: progress_update (检查同步器)
Edge->Gateway: progress_update
Gateway->Backend: progress_update
Device->Edge: progress_update (检查立柱状态)
Edge->Gateway: progress_update
Gateway->Backend: progress_update
Device->Edge: command_response (最终结果)
Edge->Gateway: command_response
Gateway->Backend: command_response
```

### 2. 程序上传流程（持续响应）

**程序上传设计思路：**
- 程序上传是独立于普通命令的特殊流程，使用专门的 `program` 和 `program_response` 消息类型
- 整个上传过程分为多个阶段：下载、解压、预处理、创建帧、上传到设备、统计
- 使用 `progress_update` 消息持续报告各阶段进度，包含：
  - `sourceType` 区分是命令操作结果还是系统类型结果
  - `context` 携带程序上下文信息，确保每个进度更新都能追溯到具体程序
  - `command` 记录涉及的设备操作（如读取配置、写入数据）
  - `report` 提供结构化的日志信息，支持不同级别和错误代码
- 最终发送 `program_response` 作为整个流程的结束标志，仅包含必要的状态信息

程序上传是长时间运行的操作，需要进度反馈：

```sequence
Backend->Gateway: program
Gateway->Edge: program
Edge->Device: program
Device->Edge: progress_update (10%)
Edge->Gateway: progress_update (10%)
Gateway->Backend: progress_update (10%)
Device->Edge: progress_update (50%)
Edge->Gateway: progress_update (50%)
Gateway->Backend: progress_update (50%)
Device->Edge: progress_update (100%)
Edge->Gateway: progress_update (100%)
Gateway->Backend: progress_update (100%)
Device->Edge: program_response
Edge->Gateway: program_response
Gateway->Backend: program_response
```

**程序上传请求：**
```json
{
  "type": "PROGRAM",
  "requestRef": "prog-123",
  "targetClientId": "td-01",
  "command": {
    "commandCode": "UPLOAD_PROGRAM",
    "parameters": {
      "deviceId": "td-01",
      "taskId": "1234567890123456789",  // Snowflake ID
      "programId": "1234567890123456788",  // Snowflake ID
      "programName": "春节活动广告",
      "programNo": 3,  // 1-10
      "programType": "DYNAMIC",  // dynamic|static
      "width": 800,
      "height": 480,
      "direction": "LEFT_TO_RIGHT",  // left_to_right|right_to_left
      "publishTime": "2024-02-01T08:00:00",  // 上刊时间（可选）
      "unpublishTime": "2024-02-15T22:00:00",  // 下刊时间（可选）
      "downloadUrl": "https://cdn.example.com/programs/v1.0.1.zip",
      "checksum": "sha256:abcd1234...",
      "hashAlgorithm": "SHA256",
      "fileSize": 10485760  // 可选
    }
  },
  "priority": "NORMAL",
  "timeout": 1800000  // 30分钟
}
```

**进度更新：**

进度更新消息用于长时间运行的操作（如程序上传），提供实时进度反馈。详细的进度更新消息格式请参考后面的《9. 程序上传流程示例》章节。

基本格式：
```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "prog-123",
  "status": "IN_PROGRESS",  // pending, in_progress, paused, completed, failed, cancelled
  "phase": "DOWNLOAD",  // 预定义阶段: DOWNLOAD, DECOMPRESS, PREPROCESS, FRAMES, UPLOAD, STATS (支持自定义阶段)
  "progress": 45,  // 0-100 的进度百分比
  "sourceType": "COMMAND",  // command（命令操作结果）或 system（系统类型结果）
  "context": {  // 可选：程序上下文信息（用于程序上传相关的进度更新）
    "taskId": "1234567890123456789",
    "programId": "1234567890123456788",
    "programName": "春节活动广告",
    "programNo": 3,
    "programType": "DYNAMIC"
  },
  "command": {  // 可选：设备操作记录
    "commandType": "SIMPLE",
    "commandCode": "READ_STATUS",
    "deviceType": "synchronizer",
    "deviceId": 1,
    "operationType": "READ",
    "result": { "status": "ready" }
  },
  "report": {  // 必需：日志信息
    "level": "INFO",
    "message": "正在下载节目文件...",
    "code": "DOWNLOAD_PROGRESS",
    "data": { "bytesDownloaded": 23592960, "totalBytes": 52428800 }
  },
  "timestamp": "2024-01-20T10:05:00Z",
  "version": "1.0"
}
```

**字段说明：**
| 字段 | 类型 | 必需 | 说明 |
|------|------|------|------|
| type | string | 是 | 固定为 "Uprogress_update" |
| requestRef | string | 是 | 原始请求的引用ID |
| status | string | 是 | 状态：pending, in_progress, paused, completed, failed, cancelled |
| phase | string | 是 | 阶段：downloading, decompressing, preprocessing, createFrames, uploading, statistics |
| progress | number | 是 | 进度百分比 (0-100) |
| sourceType | string | 是 | 来源类型：command（命令操作结果）或 system（系统类型结果） |
| context | object | 否 | 程序上下文信息（用于程序上传相关的进度更新） |
| command | object | 否 | 设备操作记录（当涉及设备读写时） |
| report | object | 是 | 日志信息（包含级别、消息、代码和数据） |
| timestamp | string | 是 | ISO 8601 格式时间戳 |
| version | string | 是 | 协议版本 "1.0" |

**阶段说明：**
- `downloading` - 下载文件
- `decompressing` - 解压文件
- `preprocessing` - 预处理
- `createFrames` - 创建帧
- `uploading` - 上传到设备
- `statistics` - 统计信息

**程序上下文字段说明：**
| 字段 | 类型 | 说明 |
|------|------|------|
| taskId | string | 任务ID (Snowflake ID) |
| programId | string | 程序ID (Snowflake ID) |
| programName | string | 程序名称 |
| programNo | number | 程序编号 (1-10) |
| programType | string | 程序类型：dynamic（动态）或 static（静态）|

**日志信息字段说明：**
| 字段 | 类型 | 必需 | 说明 |
|------|------|------|------|
| level | string | 是 | 日志级别：debug, info, warning, error, critical |
| message | string | 是 | 日志消息内容 |
| code | string | 否 | 标准化的消息代码 |
| data | object | 否 | 额外的数据对象 |

**程序上传响应：**

程序上传完成后，设备会返回最终的响应消息（作为整个流程结束的标志）：

```json
{
  "type": "PROGRAM_RESPONSE",
  "requestRef": "prog-123",
  "status": "COMPLETED",  // completed, failed, timeout, cancelled
  "context": {
    "taskId": "1234567890123456789",
    "programId": "1234567890123456788",
    "programName": "春节活动广告",
    "programNo": 3,
    "programType": "DYNAMIC"
  },
  "report": {  // 可选：日志信息
    "level": "INFO",
    "message": "程序上传并激活成功"
  },
  "executionTime": 180000,  // 可选：总执行时间（毫秒）
  "timestamp": "2024-01-20T10:30:00Z",
  "version": "1.0"
}
```

**字段说明：**
| 字段 | 类型 | 必需 | 说明 |
|------|------|------|------|
| type | string | 是 | 固定为 "Uprogram_response" |
| requestRef | string | 是 | 原始请求的引用ID |
| status | string | 是 | 状态：completed, failed, timeout, cancelled |
| context | object | 是 | 程序上下文信息（包含taskId, programId等） |
| report | object | 否 | 日志信息（使用ReportMessage结构） |
| executionTime | number | 否 | 总执行时间（毫秒） |
| timestamp | string | 是 | ISO 8601 格式时间戳 |
| version | string | 是 | 协议版本 "1.0" |

### 3. 设备状态查询

Gateway 维护所有连接设备的状态：

**查询单个设备：**
```json
{
  "type": "COMMAND",
  "requestRef": "query-001",
  "targetClientId": "Ugateway",  // 特殊值，查询Gateway
  "command": {
    "commandType": "SIMPLE",
    "commandCode": "GET_DEVICE_STATUS",
    "deviceType": "Ugateway",
    "deviceId": 0,
    "operationType": "READ",
    "parameters": {
      "targetClientId": "device001"
    }
  },
  "priority": "NORMAL",
  "timeout": 5000
}
```

**查询所有设备：**
```json
{
  "type": "COMMAND",
  "requestRef": "query-002",
  "targetClientId": "Ugateway",
  "command": {
    "commandType": "SIMPLE",
    "commandCode": "LIST_DEVICES",
    "deviceType": "Ugateway",
    "deviceId": 0,
    "operationType": "READ",
    "parameters": {
      "filter": {
        "status": "online",
        "clientType": "DEVICE"
      }
    }
  },
  "priority": "NORMAL",
  "timeout": 5000
}
```

## 错误处理

### 错误消息格式

```json
{
  "type": "ERROR",
  "code": "DEVICE_OFFLINE",
  "message": "Target device is not connected",
  "severity": "medium",  // low, medium, high, critical
  "category": "Udevice",   // device, command, protocol, system
  "context": {
    "clientId": "device001",
    "requestRef": "req-123",
    "operation": "command"
  },
  "retryable": true,
  "timestamp": "2024-01-20T10:00:00Z",
  "version": "1.0"
}
```

**严重级别说明：**
- `low` - 信息性错误，不影响系统运行
- `medium` - 一般错误，影响单个操作
- `high` - 严重错误，影响多个操作或组件
- `critical` - 关键错误，影响系统稳定性

**错误类别：**
- `device` - 设备相关错误
- `command` - 命令执行错误
- `protocol` - 协议格式或版本错误
- `system` - 系统级错误

### 错误代码规范

```
错误代码格式：[类别]_[具体错误]

设备错误 (DEVICE_)
├── DEVICE_OFFLINE      - 设备离线
├── DEVICE_NOT_FOUND    - 设备不存在
├── DEVICE_BUSY         - 设备忙
└── DEVICE_ERROR        - 设备内部错误

命令错误 (COMMAND_)
├── COMMAND_TIMEOUT     - 命令超时
├── COMMAND_INVALID     - 无效命令
├── COMMAND_FAILED      - 命令执行失败
└── COMMAND_CANCELLED   - 命令被取消

协议错误 (PROTOCOL_)
├── PROTOCOL_INVALID    - 消息格式错误
├── PROTOCOL_VERSION    - 版本不兼容
└── PROTOCOL_SEQUENCE   - 消息顺序错误

系统错误 (SYSTEM_)
├── SYSTEM_OVERLOAD     - 系统过载
├── SYSTEM_MAINTENANCE  - 系统维护
└── SYSTEM_ERROR        - 内部错误
```

### 命令失败响应示例

```json
{
  "type": "COMMAND_RESPONSE",
  "requestRef": "cmd-fail-001",
  "status": "FAILED",
  "result": {
    "deviceType": "pillar",
    "deviceId": 5,
    "commandCode": "TRAIN_LENGTH",
    "operationType": "WRITE",
    "data": {
      "attemptedValue": 8,
      "currentValue": 6,
      "errorReason": "Invalid train length"
    }
  },
  "report": {
    "level": "ERROR",
    "message": "命令执行失败：列车长度设置无效",
    "code": "COMMAND_FAILED",
    "data": {
      "retryable": false,
      "maxLength": 6,
      "attemptedLength": 8
    }
  },
  "executionTime": 45,
  "timestamp": "2024-01-20T10:05:00Z",
  "version": "1.0"
}
```

### 错误处理策略

1. **自动重试** - 对于 `retryable: true` 的错误
2. **降级处理** - 批量操作失败时降级为单个操作
3. **熔断保护** - 连续失败时暂停发送
4. **错误聚合** - 相似错误合并上报

## 安全性

### 1. 认证机制

虽然基础协议不强制认证，但建议实现：

```json
{
  "type": "REGISTER",
  "clientId": "device001",
  "auth": {  // 可选
    "method": "token",
    "credentials": "Bearer eyJhbGc..."
  }
}
```

### 2. 消息完整性

对于关键命令，支持消息签名：

```json
{
  "type": "COMMAND",
  "requestRef": "secure-req-123",
  "signature": "sha256:1234abcd...",  // 可选
  // ... 其他字段
}
```

### 3. 访问控制

Gateway 实现基于客户端类型的访问控制：

- **Backend**: 可以发送命令给任何 Edge 管理的设备
- **Edge**: 可以转发其管理的设备状态，执行来自 Backend 的命令
- **Device**: 不直接连接 Gateway，由 Edge 代理所有通信

## 性能优化

### 1. 消息压缩

对于大型消息（>1KB），Gateway 支持压缩：

```
WebSocket Header: Compression: gzip
```

### 2. 批量处理

支持批量消息以减少往返次数：

```json
{
  "type": "Ubatch",  // 批量类型
  "messages": [
    { "type": "COMMAND", ... },
    { "type": "COMMAND", ... },
    { "type": "COMMAND", ... }
  ]
}
```

### 3. 消息优先级

Gateway 根据优先级处理消息：

- **critical**: 立即处理
- **high**: 优先处理
- **normal**: 标准队列
- **low**: 空闲时处理

## 版本管理


### 版本要求

当前协议版本为 1.0，所有组件必须使用相同版本。

## 命令系统架构

### 强类型命令支持

协议支持两种命令定义方式：

1. **强类型命令** - 基于 C# 模型生成的类型安全命令
2. **通用命令** - 灵活的键值对参数命令

**注意**：不同命令类型的字段要求：
- **Simple 类型**：需要 commandCode, deviceType, deviceId, operationType, parameters
- **Batch 类型**：需要 commandCode, deviceType, deviceId（可为范围字符串）, operationType, parameters
- **Complex 类型**：只需要 commandCode, parameters（不需要 deviceType, deviceId 和 operationType）

```typescript
// 强类型命令定义
export interface LedSwitchCommand {
  commandCode: 'LedSwitch';
  deviceType: 'pillar';
  deviceId: number;
  operationType: 'read' | 'write';
  parameters?: {
    switch: 'ON' | 'OFF';
  };
}

// 使用强类型工厂
const command = createLedSwitchCommand(
  'req-123', 'device-001', 15, 'ON', 'write'
);
```

### 批量命令支持

向同一设备端的多个同类型子硬件发送相同命令：

```json
{
  "command": {
    "commandCode": "SET_COLOR",
    "deviceType": "light_column",
    "parameters": {
      "targets": "1-10,30-40,51,52,53,54",  // 范围表示法
      "Ubatch": true,
      "color": "#FF0000"
    }
  }
}
```

## 10. 程序上传流程示例

完整的程序上传流程及其进度更新：

### 10.1 初始程序上传命令
```json
{
  "type": "PROGRAM",
  "requestRef": "prog-upload-001",
  "targetClientId": "device-001",
  "command": {
    "commandCode": "UPLOAD_PROGRAM",
    "parameters": {
      "deviceId": "device-001",
      "taskId": "1234567890123456789",
      "programId": "1234567890123456788",
      "programName": "春节活动广告",
      "programNo": 1,
      "programType": "DYNAMIC",
      "width": 1920,
      "height": 1080,
      "direction": "LEFT_TO_RIGHT",
      "publishTime": "2024-02-01T00:00:00Z",  // 可选
      "unpublishTime": "2024-02-15T23:59:59Z",  // 可选
      "downloadUrl": "https://example.com/programs/spring-festival.zip",
      "checksum": "a1b2c3d4e5f6...",
      "hashAlgorithm": "SHA256",
      "fileSize": 52428800  // 可选
    }
  },
  "priority": "HIGH",
  "timeout": 1800000,
  "timestamp": "2024-01-20T10:00:00Z",
  "version": "1.0"
}
```

### 10.2 进度更新序列

#### 阶段1：下载文件
```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "prog-upload-001",
  "status": "IN_PROGRESS",
  "phase": "DOWNLOAD",
  "progress": 0,
  "sourceType": "SYSTEM",
  "context": {
    "taskId": "1234567890123456789",
    "programId": "1234567890123456788",
    "programName": "春节活动广告",
    "programNo": 3,
    "programType": "DYNAMIC"
  },
  "report": {
    "level": "INFO",
    "message": "开始下载节目文件..."
  },
  "timestamp": "2024-01-20T10:00:01Z",
  "version": "1.0"
}
```

```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "prog-upload-001",
  "status": "IN_PROGRESS",
  "phase": "DOWNLOAD",
  "progress": 50,
  "sourceType": "SYSTEM",
  "report": {
    "level": "DEBUG",
    "message": "已下载 25MB / 50MB",
    "data": {
      "downloadSpeed": "5.2MB/s",
      "remainingTime": 10,
      "serverLatency": 32
    }
  },
  "timestamp": "2024-01-20T10:00:30Z",
  "version": "1.0"
}
```

#### 阶段2：解压文件
```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "prog-upload-001",
  "status": "IN_PROGRESS",
  "phase": "DECOMPRESS",
  "progress": 15,
  "sourceType": "SYSTEM",
  "report": {
    "level": "INFO",
    "message": "正在解压节目文件..."
  },
  "timestamp": "2024-01-20T10:01:00Z",
  "version": "1.0"
}
```

#### 阶段3：预处理
```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "prog-upload-001",
  "status": "IN_PROGRESS",
  "phase": "PREPROCESS",
  "progress": 20,
  "sourceType": "SYSTEM",
  "report": {
    "level": "INFO",
    "message": "正在验证节目内容..."
  },
  "timestamp": "2024-01-20T10:01:30Z",
  "version": "1.0"
}
```

#### 预处理中的警告日志
```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "prog-upload-001",
  "status": "IN_PROGRESS",
  "phase": "PREPROCESS",
  "progress": 25,
  "sourceType": "SYSTEM",
  "report": {
    "message": "发现节目格式问题，正在尝试修复...",
    "level": "WARNING",
    "code": "FORMAT_ISSUE_DETECTED",
    "data": {
      "issue": "invalid_resolution",
      "expected": "1920x1080",
      "actual": "1920x1088",
      "action": "auto_crop"
    }
  },
  "timestamp": "2024-01-20T10:01:35Z",
  "version": "1.0"
}
```

#### 阶段4：创建帧（包含设备读取）
```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "prog-upload-001",
  "status": "IN_PROGRESS",
  "phase": "FRAMES",
  "progress": 40,
  "sourceType": "COMMAND",
  "report": {
    "level": "INFO",
    "message": "正在读取设备配置..."
  },
  "context": {
    "taskId": "1234567890123456789",
    "programId": "1234567890123456788",
    "programName": "春节活动广告",
    "programNo": 3,
    "programType": "DYNAMIC"
  },
  "command": {
    "commandType": "SIMPLE",
    "commandCode": "READ_DISPLAY_CONFIG",
    "deviceType": "display",
    "deviceId": 1,
    "operationType": "READ",
    "result": {
      "resolution": "1920x1080",
      "colorDepth": 24,
      "refreshRate": 60
    }
  },
  "timestamp": "2024-01-20T10:02:00Z",
  "version": "1.0"
}
```

#### 阶段5：上传到设备（包含设备写入）
```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "prog-upload-001",
  "status": "IN_PROGRESS",
  "phase": "UPLOAD",
  "progress": 60,
  "sourceType": "COMMAND",
  "report": {
    "level": "INFO",
    "message": "正在写入节目数据到设备..."
  },
  "command": {
    "commandType": "SIMPLE",
    "commandCode": "WRITE_PROGRAM_DATA",
    "deviceType": "storage",
    "deviceId": 1,
    "operationType": "WRITE",
    "result": {
      "blocksWritten": 512,
      "totalBlocks": 1024,
      "writeSpeed": "10MB/s"
    }
  },
  "timestamp": "2024-01-20T10:03:00Z",
  "version": "1.0"
}
```

#### 阶段6：统计信息
```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "prog-upload-001",
  "status": "COMPLETED",
  "phase": "STATS",
  "progress": 100,
  "sourceType": "COMMAND",
  "report": {
    "level": "INFO",
    "message": "节目上传完成"
  },
  "command": {
    "commandType": "SIMPLE",
    "commandCode": "FINALIZE_PROGRAM",
    "deviceType": "controller",
    "deviceId": 1,
    "operationType": "WRITE",
    "result": {
      "programId": "1234567890123456788",
      "programNo": 1,
      "totalFrames": 7200,
      "checksum": "a1b2c3d4e5f6..."
    }
  },
  "report": {
    "level": "INFO",
    "code": "UPLOAD_STATS",
    "data": {
      "totalTime": 240,
      "downloadTime": 60,
      "processTime": 120,
      "uploadTime": 60,
      "averageSpeed": "218KB/s",
      "peakMemoryUsage": "256MB"
    }
  },
  "timestamp": "2024-01-20T10:04:00Z",
  "version": "1.0"
}
```

### 10.3 最终响应
```json
{
  "type": "PROGRAM_RESPONSE",
  "requestRef": "prog-upload-001",
  "status": "COMPLETED",
  "context": {
    "taskId": "1234567890123456789",
    "programId": "1234567890123456788",
    "programName": "春节活动广告",
    "programNo": 3,
    "programType": "DYNAMIC"
  },
  "report": {
    "level": "INFO",
    "message": "程序上传成功"
  },
  "executionTime": 240000,
  "timestamp": "2024-01-20T10:04:01Z",
  "version": "1.0"
}
```

#### 失败响应示例
```json
{
  "type": "PROGRAM_RESPONSE",
  "requestRef": "prog-upload-002",
  "status": "FAILED",
  "context": {
    "taskId": "1234567890123456789",
    "programId": "1234567890123456788",
    "programName": "春节活动广告",
    "programNo": 3,
    "programType": "DYNAMIC"
  },
  "report": {
    "level": "ERROR",
    "message": "设备存储空间不足",
    "code": "INSUFFICIENT_STORAGE",
    "data": {
      "availableSpace": 10485760,
      "requiredSpace": 52428800,
      "retryable": false
    }
  },
  "executionTime": 180000,
  "timestamp": "2024-01-20T10:03:00Z",
  "version": "1.0"
}
```

### 10.4 错误状态示例

#### 暂停状态
```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "prog-upload-001",
  "status": "PAUSED",
  "phase": "UPLOAD",
  "progress": 75,
  "sourceType": "SYSTEM",
  "report": {
    "level": "WARNING",
    "message": "程序上传已暂停"
  },
  "timestamp": "2024-01-20T10:03:30Z",
  "version": "1.0"
}
```

#### 失败状态
```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "prog-upload-001",
  "status": "FAILED",
  "phase": "UPLOAD",
  "progress": 75,
  "sourceType": "COMMAND",
  "report": {
    "level": "ERROR",
    "message": "设备写入失败：内存空间不足",
    "code": "DEVICE_WRITE_ERROR"
  },
  "command": {
    "commandType": "SIMPLE",
    "commandCode": "WRITE_MEMORY",
    "deviceType": "storage",
    "deviceId": 1,
    "operationType": "WRITE",
    "result": {
      "Uerror": "INSUFFICIENT_SPACE",
      "availableSpace": 512,
      "requiredSpace": 2048
    }
  },
  "report": {
    "level": "ERROR",
    "code": "DEVICE_WRITE_ERROR",
    "data": {
      "retryCount": 3,
      "lastAttempt": "2024-01-20T10:01:58Z"
    }
  },
  "timestamp": "2024-01-20T10:02:00Z",
  "version": "1.0"
}
```

#### 取消状态
```json
{
  "type": "PROGRESS_UPDATE",
  "requestRef": "prog-upload-001",
  "status": "CANCELLED",
  "phase": "DOWNLOAD",
  "progress": 30,
  "sourceType": "SYSTEM",
  "report": {
    "level": "WARNING",
    "message": "用户取消了程序上传"
  },
  "timestamp": "2024-01-20T10:00:45Z",
  "version": "1.0"
}
```

## 11. 协议版本

当前协议版本为 `1.0`。所有消息都必须包含 `version` 字段。

## 12. 附录：命令代码参考

### 通用命令
- `PING` - 连通性测试
- `GET_INFO` - 获取设备信息

### 强类型命令（C# 模型定义）
- `LedSwitch` - LED 开关控制
- `BlockPlay` - 区块播放控制
- `HealthCheck` - 健康检查
- `MeterEnergy` - 能耗计量
- `PowerSwitch` - 电源开关
- `ProgramBrightness` - 亮度调节
- `SpeedCorrection` - 速度校正
- `TimeSynchronization` - 时间同步
- 更多命令参见 C# 模型项目
- `GET_STATUS` - 获取设备状态
- `RESET` - 重置设备

### 控制命令
- `START` - 启动
- `STOP` - 停止
- `PAUSE` - 暂停
- `RESUME` - 恢复

### 配置命令
- `GET_CONFIG` - 读取配置
- `SET_CONFIG` - 设置配置
- `SAVE_CONFIG` - 保存配置
- `RESTORE_CONFIG` - 恢复配置

### 数据命令
- `READ_REGISTER` - 读取寄存器
- `WRITE_REGISTER` - 写入寄存器
- `READ_MEMORY` - 读取内存
- `WRITE_MEMORY` - 写入内存

### 程序命令
- `UPLOAD_PROGRAM` - 上传程序
- `VERIFY_PROGRAM` - 验证程序
- `ACTIVATE_PROGRAM` - 激活程序
- `DELETE_PROGRAM` - 删除程序

---

*本规范为 JRSoft Subway 项目的核心协议定义，所有组件实现必须遵循此规范。*