# Gateway vs Protocol 类型定义比较

## BaseMessage 比较

### Gateway 定义
```typescript
export interface BaseMessage {
  type: MessageType;
  targetClientId?: string;
}
```

### Protocol 定义
```typescript
export interface BaseMessage {
  type: MessageType;
  timestamp: string;  // ISO 8601 格式
  version: string;    // 协议版本 "1.0"
}
```

### 差异分析
| 字段 | Gateway | Protocol | 说明 |
|------|---------|----------|------|
| type | ✓ | ✓ | 都有，类型一致 |
| targetClientId | ✓ (可选) | ✗ | Gateway 特有，但应该只在特定消息中使用 |
| timestamp | ✗ | ✓ (必需) | Protocol 要求所有消息都有时间戳 |
| version | ✗ | ✓ (必需) | Protocol 要求协议版本号 |

## CommandMessage 比较

### Gateway 定义
```typescript
export interface CommandMessage extends BaseMessage {
  type: typeof WS_MESSAGE_TYPES.COMMAND;
  requestRef: string;
  targetClientId: string;
  command: {
    commandType?: 'SIMPLE' | 'BATCH' | 'COMPLEX';
    commandCode: string;
    deviceType: string;
    deviceId?: number;
    operationType: string;
    parameters: Record<string, unknown>;
  };
  priority: string;
  timeout: number;
  timestamp: string;
  callback?: string;
  version?: string;
  metadata?: Record<string, any>;
}
```

### Protocol 定义
```typescript
export interface CommandMessage extends BaseMessage {
  type: MessageType.COMMAND;
  requestRef: string;
  targetClientId: string;
  command: Command;  // 支持多种命令类型
  priority: Priority;  // 枚举类型
  timeout: number;
  retryCount?: number;
  callback: string;
  metadata?: Record<string, any>;
}

// Command 可以是:
// - SpecificCommand (从 C# 生成)
// - SimpleCommand
// - BatchCommand
// - ComplexCommand
// - GenericCommand
```

### 详细差异分析

#### 1. 继承的差异
- **Gateway**: 继承的 BaseMessage 有 `targetClientId?`
- **Protocol**: 继承的 BaseMessage 有 `timestamp` 和 `version`

#### 2. 字段级别差异

| 字段 | Gateway | Protocol | 差异说明 |
|------|---------|----------|----------|
| requestRef | ✓ string | ✓ string | ✅ 一致 |
| targetClientId | ✓ string | ✓ string | ✅ 一致 |
| command | 内联对象 | Command 类型 | ⚠️ Protocol 使用强类型 |
| priority | string | Priority 枚举 | ⚠️ Protocol 使用枚举 |
| timeout | ✓ number | ✓ number | ✅ 一致 |
| timestamp | ✓ string | 继承自 BaseMessage | ⚠️ Gateway 直接定义，Protocol 继承 |
| callback | ✓ 可选 | ✓ 必需 | ❌ **重要差异** |
| version | ✓ 可选 | 继承自 BaseMessage | ⚠️ Gateway 直接定义，Protocol 继承 |
| retryCount | ✗ | ✓ 可选 | ⚠️ Protocol 特有 |
| metadata | ✓ 可选 | ✓ 可选 | ✅ 一致 |

#### 3. Command 结构差异

**Gateway 的 command**:
```typescript
command: {
  commandType?: 'SIMPLE' | 'BATCH' | 'COMPLEX';
  commandCode: string;
  deviceType: string;
  deviceId?: number;
  operationType: string;
  parameters: Record<string, unknown>;
}
```

**Protocol 的 command**:
- 支持多种类型（SimpleCommand, BatchCommand, ComplexCommand, GenericCommand）
- deviceId 支持 `number | number[] | string`
- 有严格的类型定义和验证

## 其他消息类型差异

### RegisterMessage
**主要差异**:
- Gateway: `clientType: 'device' | 'edge' | 'backend'`
- Protocol: `clientType: ClientType` (枚举)
- Gateway: 没有 timestamp 和 version
- Protocol: 继承自 BaseMessage，有 timestamp 和 version

### RegisterAckMessage
**主要差异**:
- Gateway: `message?: string`
- Protocol: `error?: { code: string; message: string }`
- Protocol 有更详细的 serverInfo

## 字段一致性总结

### CommandMessage 完全一致的字段：
- `requestRef: string` ✅
- `targetClientId: string` ✅
- `timeout: number` ✅
- `metadata?: Record<string, any>` ✅

### 主要差异字段：
1. **callback**: Gateway 可选 vs Protocol 必需 ❌
2. **priority**: Gateway 字符串 vs Protocol 枚举 ⚠️
3. **command**: Gateway 内联对象 vs Protocol 强类型 ⚠️
4. **retryCount**: 只在 Protocol 中存在 ⚠️

## 统一建议

### 1. BaseMessage 统一
```typescript
// 建议的统一定义
export interface BaseMessage {
  type: MessageType;
  timestamp: string;    // 必需，便于追踪
  version: string;      // 必需，便于版本管理
  // targetClientId 不应该在这里，只在需要的消息中定义
}
```

### 2. CommandMessage 统一
需要决定：
- **callback**: 是否必需？
- **priority**: 使用枚举还是字符串？
- **command**: 使用强类型还是松散对象？

### 3. 迁移步骤
1. Gateway 先迁移到使用协议包
2. 处理字段差异（添加 timestamp, version）
3. 统一类型定义（枚举 vs 字符串）
4. 更新验证逻辑

## 影响评估

### 如果采用 Protocol 的严格定义
**需要修改 Gateway**:
1. 所有消息添加 timestamp 和 version
2. callback 改为必需（或修改协议使其可选）
3. priority 使用 Priority 枚举
4. 移除 BaseMessage 中的 targetClientId

### 如果放松 Protocol 的定义
**需要修改 Protocol**:
1. callback 改为可选
2. priority 改为可选并提供默认值
3. 可能需要调整验证逻辑

## 推荐方案

1. **保持 Protocol 的严格定义**（推荐）
   - 更好的类型安全
   - 清晰的 API 契约
   - Gateway 迁移到使用协议包

2. **创建适配层**
   - Gateway 保持现有定义
   - 创建转换函数在 Gateway 和 Protocol 之间转换
   - 逐步迁移

3. **放松 Protocol 定义**
   - 使某些字段可选
   - 降低迁移成本
   - 但可能导致运行时错误

## 更新说明

### 关于 timeout 字段
经过检查，`timeout` 字段在 Gateway 和 Protocol 的 CommandMessage 定义中都存在，都是必需的 `number` 类型。这不是差异点。

### Backend 使用情况
- Backend 已经完全迁移到使用 `@jrsoft/subway-protocol`
- Backend 的 `gateway.client.ts` 和 `command.dispatcher.ts` 都使用了协议包的类型定义
- Backend 中的 callback 使用 `appConfig.gateway.callbackUrl` 作为值

### Gateway 使用情况  
- Gateway 仍在使用自己的类型定义文件 (`src/types/common.types.ts`)
- Gateway 尚未迁移到协议包
- Gateway 的 callback 字段是可选的，这是主要差异之一