# 常见问题解答（FAQ）

## 协议相关

### Q: 为什么选择 WebSocket 而不是 HTTP？

A: WebSocket 提供了实时双向通信能力，非常适合我们的场景：
- **实时性**：设备状态变化需要立即通知
- **双向通信**：设备既要接收命令，也要主动上报状态
- **低延迟**：避免 HTTP 轮询的开销
- **持久连接**：减少连接建立的开销

### Q: 协议版本如何管理？

A: 当前协议版本为 1.0，升级策略：
- 所有消息包含 `version` 字段
- 向后兼容：新版本支持旧版本消息
- 版本协商：注册时确定使用的协议版本
- 平滑升级：支持新旧版本并存

### Q: 消息大小有限制吗？

A: 建议限制：
- 单个消息不超过 1MB
- 大文件通过 URL 下载，而非消息体
- 批量数据分页传输
- 支持消息压缩（gzip）

### Q: 如何保证消息的可靠性？

A: 多层保障机制：
- WebSocket 基于 TCP，保证顺序和完整性
- 心跳机制检测连接状态
- 请求-响应模式确认执行结果
- 支持重试和超时处理
- 关键操作支持回调确认

## 集成问题

### Q: 如何处理网络断开重连？

A: 推荐的重连策略：
```javascript
class ReconnectingWebSocket {
  constructor(url) {
    this.url = url;
    this.reconnectInterval = 1000;
    this.maxReconnectInterval = 30000;
    this.reconnectDecay = 1.5;
    this.reconnectAttempts = 0;
  }

  connect() {
    this.ws = new WebSocket(this.url);
    
    this.ws.onclose = () => {
      this.reconnect();
    };
    
    this.ws.onopen = () => {
      this.reconnectAttempts = 0;
      this.register(); // 重新注册
    };
  }

  reconnect() {
    const timeout = Math.min(
      this.reconnectInterval * Math.pow(this.reconnectDecay, this.reconnectAttempts),
      this.maxReconnectInterval
    );
    
    setTimeout(() => {
      this.reconnectAttempts++;
      this.connect();
    }, timeout);
  }
}
```

### Q: Edge 设备注册的正确流程是什么？

A: Edge 和设备的注册流程：

1. **Edge 先注册自己**
```json
{
  "type": "REGISTER",
  "clientId": "edge-001",
  "clientType": "EDGE"
}
```

2. **Edge 为每个设备注册**
```json
{
  "type": "REGISTER",
  "clientId": "td-01",
  "clientType": "DEVICE",
  "edgeInfo": {
    "edgeId": "edge-001"
  }
}
```

### Q: 如何实现批量命令的进度跟踪？

A: 使用 progress_update 消息：
```javascript
// 批量执行示例
async function executeBatchCommand(devices, command) {
  const total = devices.length;
  let completed = 0;
  
  for (const device of devices) {
    try {
      const result = await executeOnDevice(device, command);
      completed++;
      
      // 发送进度更新
      await sendProgressUpdate({
        requestRef: command.requestRef,
        status: 'IN_PROGRESS',
        progress: Math.round((completed / total) * 100),
        phase: 'executing',
        command: {
          deviceId: device.id,
          result: result
        }
      });
    } catch (error) {
      // 处理错误但继续执行
    }
  }
  
  // 发送最终响应
  return {
    type: 'COMMAND_RESPONSE',
    status: 'COMPLETED',
    summary: { total, completed }
  };
}
```

### Q: 心跳机制的最佳实践？

A: 推荐配置：
- 发送间隔：30秒
- 超时时间：90秒（3个心跳周期）
- 包含序列号用于匹配
- 利用心跳确认携带服务器状态

```javascript
class HeartbeatManager {
  constructor(websocket, clientId) {
    this.ws = websocket;
    this.clientId = clientId;
    this.sequence = 0;
    this.interval = 30000; // 30秒
  }
  
  start() {
    this.timer = setInterval(() => {
      this.send();
    }, this.interval);
  }
  
  send() {
    this.ws.send(JSON.stringify({
      type: 'HEARTBEAT',
      clientId: this.clientId,
      sequence: ++this.sequence,
      clientTime: new Date().toISOString(),
      timestamp: new Date().toISOString(),
      version: '1.0'
    }));
  }
  
  stop() {
    clearInterval(this.timer);
  }
}
```

## 性能优化

### Q: 如何优化大量设备的消息推送？

A: 性能优化策略：
1. **消息聚合**：相同的命令合并发送
2. **批量处理**：使用 BATCH 命令类型
3. **优先级队列**：重要消息优先处理
4. **限流控制**：避免消息风暴
5. **Edge 缓存**：利用 Edge 节点缓存

### Q: Gateway 的负载均衡如何实现？

A: 多种负载均衡策略：
- **连接数均衡**：新连接分配到连接数最少的 Gateway
- **消息量均衡**：根据消息吞吐量分配
- **地理位置**：就近接入原则
- **设备类型**：特定设备类型分配到特定 Gateway

### Q: 如何处理消息积压？

A: 消息积压处理：
1. **监控队列长度**：设置阈值告警
2. **优先级处理**：优先处理高优先级消息
3. **过期丢弃**：超时消息直接丢弃
4. **反压控制**：通知发送方降速
5. **水平扩展**：增加处理节点

## 故障排查

### Q: 设备无法连接到 Gateway？

A: 排查步骤：
1. **网络连通性**：ping Gateway 地址
2. **端口开放**：telnet Gateway 18081端口
3. **防火墙规则**：检查防火墙设置
4. **证书问题**：如果使用 WSS，检查证书
5. **日志分析**：查看 Gateway 和设备日志

### Q: 命令执行超时如何处理？

A: 超时处理机制：
```javascript
async function executeCommandWithTimeout(command, timeout = 30000) {
  return Promise.race([
    executeCommand(command),
    new Promise((_, reject) => 
      setTimeout(() => reject(new Error('Command timeout')), timeout)
    )
  ]);
}
```

### Q: 如何调试协议消息？

A: 调试工具和方法：
1. **浏览器开发工具**：查看 WebSocket 消息
2. **Wireshark**：网络层抓包分析
3. **日志记录**：记录所有收发消息
4. **Mock Server**：模拟 Gateway 进行测试

```javascript
// 消息日志中间件
function messageLogger(direction) {
  return (message) => {
    console.log(`[${new Date().toISOString()}] ${direction}:`, 
      JSON.stringify(message, null, 2));
    return message;
  };
}
```

## 安全相关

### Q: 如何保证通信安全？

A: 安全措施：
1. **使用 WSS**：WebSocket over TLS
2. **Token 认证**：注册时验证身份
3. **消息签名**：关键命令签名验证
4. **访问控制**：基于客户端类型的权限控制
5. **审计日志**：记录所有操作

### Q: 如何防止恶意连接？

A: 防护措施：
- **连接限流**：限制单 IP 连接数
- **认证超时**：未认证连接自动断开
- **黑名单**：恶意 IP 自动封禁
- **异常检测**：异常行为模式识别

## 扩展性

### Q: 如何添加新的命令类型？

A: 扩展步骤：
1. 在 C# 模型项目中定义命令
2. 生成 TypeScript 类型定义
3. 实现命令处理逻辑
4. 更新文档
5. 版本兼容性测试

### Q: 如何支持新的设备类型？

A: 新设备接入：
1. 定义设备类型和能力
2. 实现设备通信适配器
3. 注册设备命令映射
4. 测试各种命令场景
5. 更新设备管理文档

### Q: 协议如何支持未来扩展？

A: 扩展性设计：
- **版本字段**：支持协议演进
- **通用字段**：metadata、context 等扩展字段
- **自定义命令**：GenericCommand 支持任意命令
- **插件机制**：Gateway 和 Edge 支持插件
- **向后兼容**：新版本兼容旧版本消息