@thejrsoft/subway-protocol 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/ACK_MESSAGES_IMPLEMENTATION_SUMMARY.md +128 -0
  2. package/ACK_MESSAGE_DESIGN.md +457 -0
  3. package/CHANGELOG.md +58 -0
  4. package/COMMAND_VALIDATION_RULES.md +178 -0
  5. package/DOCUMENTATION_REORGANIZATION_SUMMARY.md +81 -0
  6. package/DOCUMENTATION_STRUCTURE.md +106 -0
  7. package/GATEWAY_MIGRATION_GUIDE.md +130 -0
  8. package/GATEWAY_PROTOCOL_COMPARISON.md +216 -0
  9. package/INTEGRATION_GUIDE.md +190 -0
  10. package/OPTIONAL_FIELDS_WITHOUT_DEFAULTS.md +97 -0
  11. package/PROTOCOL_UTILS_USAGE.md +278 -0
  12. package/README.md +237 -0
  13. package/TYPE_FIXES_SUMMARY.md +210 -0
  14. package/UPDATE_ENUM_VALUES.md +139 -0
  15. package/dist/asyncapi-sync.d.ts +47 -0
  16. package/dist/asyncapi-sync.d.ts.map +1 -0
  17. package/dist/asyncapi-sync.js +85 -0
  18. package/dist/asyncapi-sync.js.map +1 -0
  19. package/dist/command-factory.d.ts +62 -0
  20. package/dist/command-factory.d.ts.map +1 -0
  21. package/dist/command-factory.js +137 -0
  22. package/dist/command-factory.js.map +1 -0
  23. package/dist/command-types.d.ts +27 -0
  24. package/dist/command-types.d.ts.map +1 -0
  25. package/dist/command-types.js +31 -0
  26. package/dist/command-types.js.map +1 -0
  27. package/dist/index.d.ts +403 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +413 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/message-validator.d.ts +102 -0
  32. package/dist/message-validator.d.ts.map +1 -0
  33. package/dist/message-validator.js +640 -0
  34. package/dist/message-validator.js.map +1 -0
  35. package/dist/protocol-utils.d.ts +108 -0
  36. package/dist/protocol-utils.d.ts.map +1 -0
  37. package/dist/protocol-utils.js +293 -0
  38. package/dist/protocol-utils.js.map +1 -0
  39. package/docs/01-protocol/README.md +45 -0
  40. package/docs/01-protocol/design-rationale.md +198 -0
  41. package/docs/01-protocol/message-types.md +669 -0
  42. package/docs/01-protocol/specification.md +1466 -0
  43. package/docs/02-commands/README.md +56 -0
  44. package/docs/02-commands/batch-command.md +435 -0
  45. package/docs/02-commands/complex-command.md +537 -0
  46. package/docs/02-commands/simple-command.md +332 -0
  47. package/docs/02-commands/typed-commands.md +362 -0
  48. package/docs/03-architecture/README.md +66 -0
  49. package/docs/03-architecture/device-protocol.md +430 -0
  50. package/docs/03-architecture/edge-proxy.md +727 -0
  51. package/docs/03-architecture/routing-flow.md +893 -0
  52. package/docs/04-integration/README.md +144 -0
  53. package/docs/04-integration/backend-guide.md +551 -0
  54. package/docs/04-integration/edge-guide.md +684 -0
  55. package/docs/04-integration/gateway-guide.md +180 -0
  56. package/docs/04-integration/migration-guide.md +226 -0
  57. package/docs/05-examples/README.md +141 -0
  58. package/docs/05-examples/progress-update-examples.md +757 -0
  59. package/docs/06-reference/README.md +67 -0
  60. package/docs/06-reference/api.md +572 -0
  61. package/docs/06-reference/faq.md +302 -0
  62. package/docs/06-reference/glossary.md +232 -0
  63. package/examples/backend-upgrade.ts +279 -0
  64. package/examples/edge-multi-device.ts +513 -0
  65. package/examples/gateway-upgrade.ts +150 -0
  66. package/examples/protocol-implementation.ts +715 -0
  67. package/package.json +48 -0
  68. package/scripts/validate-asyncapi.ts +78 -0
  69. package/src/__tests__/protocol.test.ts +297 -0
  70. package/src/asyncapi-sync.ts +84 -0
  71. package/src/command-factory.ts +183 -0
  72. package/src/command-types.ts +72 -0
  73. package/src/edge-proxy.ts +494 -0
  74. package/src/gateway-extensions.ts +278 -0
  75. package/src/index.ts +792 -0
  76. package/src/message-validator.ts +726 -0
  77. package/src/protocol-utils.ts +355 -0
  78. package/tsconfig.json +24 -0
@@ -0,0 +1,757 @@
1
+ # Progress Update 示例
2
+
3
+ 本文档展示如何使用 progress_update 消息进行进度报告。
4
+
5
+ ## 基本概念
6
+
7
+ Progress Update 用于长时间运行操作的实时进度反馈,适用于:
8
+ - Complex 命令执行
9
+ - Batch 命令批量处理
10
+ - Program 程序上传
11
+ - 任何需要进度反馈的操作
12
+
13
+ ## Complex 命令进度更新
14
+
15
+ ### 健康检查示例
16
+
17
+ ```typescript
18
+ // 设备端实现
19
+ class HealthCheckHandler {
20
+ async executeHealthCheck(command: CommandMessage, gateway: GatewayConnection) {
21
+ const requestRef = command.requestRef;
22
+ const totalSteps = 4;
23
+ let currentStep = 0;
24
+
25
+ try {
26
+ // Step 1: 检查开关状态
27
+ currentStep++;
28
+ const switchStatus = await this.checkSwitchStatus();
29
+
30
+ await gateway.sendProgressUpdate({
31
+ type: MessageType.PROGRESS_UPDATE,
32
+ requestRef,
33
+ status: ProgressStatus.IN_PROGRESS,
34
+ phase: 'checking_switch',
35
+ progress: (currentStep / totalSteps) * 100,
36
+ sourceType: 'COMMAND',
37
+ command: {
38
+ commandType: CommandType.SIMPLE,
39
+ commandCode: 'READ_SWITCH_STATUS',
40
+ deviceType: 'controller',
41
+ deviceId: this.deviceId,
42
+ operationType: OperationType.READ,
43
+ result: switchStatus
44
+ },
45
+ report: {
46
+ level: ReportLevel.INFO,
47
+ message: '开关状态检查完成',
48
+ data: { switchCount: switchStatus.count }
49
+ },
50
+ timestamp: new Date().toISOString(),
51
+ version: '1.0'
52
+ });
53
+
54
+ // Step 2: 读取配置
55
+ currentStep++;
56
+ const config = await this.readConfiguration();
57
+
58
+ await gateway.sendProgressUpdate({
59
+ type: MessageType.PROGRESS_UPDATE,
60
+ requestRef,
61
+ status: ProgressStatus.IN_PROGRESS,
62
+ phase: 'reading_config',
63
+ progress: (currentStep / totalSteps) * 100,
64
+ sourceType: 'COMMAND',
65
+ command: {
66
+ commandType: CommandType.SIMPLE,
67
+ commandCode: 'READ_CONFIG',
68
+ deviceType: 'controller',
69
+ deviceId: this.deviceId,
70
+ operationType: OperationType.READ,
71
+ result: config
72
+ },
73
+ report: {
74
+ level: ReportLevel.INFO,
75
+ message: '配置读取完成'
76
+ },
77
+ timestamp: new Date().toISOString(),
78
+ version: '1.0'
79
+ });
80
+
81
+ // Step 3: 检查同步器
82
+ currentStep++;
83
+ const syncStatus = await this.checkSynchronizer();
84
+
85
+ await gateway.sendProgressUpdate({
86
+ type: MessageType.PROGRESS_UPDATE,
87
+ requestRef,
88
+ status: ProgressStatus.IN_PROGRESS,
89
+ phase: 'checking_synchronizer',
90
+ progress: (currentStep / totalSteps) * 100,
91
+ sourceType: 'COMMAND',
92
+ command: {
93
+ commandType: CommandType.SIMPLE,
94
+ commandCode: 'CHECK_SYNC',
95
+ deviceType: 'synchronizer',
96
+ deviceId: 1,
97
+ operationType: OperationType.READ,
98
+ result: syncStatus
99
+ },
100
+ report: {
101
+ level: syncStatus.healthy ? ReportLevel.INFO : ReportLevel.WARNING,
102
+ message: syncStatus.healthy ? '同步器状态正常' : '同步器存在问题',
103
+ code: syncStatus.healthy ? 'SYNC_OK' : 'SYNC_WARNING',
104
+ data: syncStatus
105
+ },
106
+ timestamp: new Date().toISOString(),
107
+ version: '1.0'
108
+ });
109
+
110
+ // Step 4: 检查光柱
111
+ currentStep++;
112
+ const pillarStatus = await this.checkPillars();
113
+
114
+ await gateway.sendProgressUpdate({
115
+ type: MessageType.PROGRESS_UPDATE,
116
+ requestRef,
117
+ status: ProgressStatus.IN_PROGRESS,
118
+ phase: 'checking_pillars',
119
+ progress: 100,
120
+ sourceType: 'COMMAND',
121
+ command: {
122
+ commandType: CommandType.SIMPLE,
123
+ commandCode: 'CHECK_PILLARS',
124
+ deviceType: 'pillar',
125
+ deviceId: 'all',
126
+ operationType: OperationType.READ,
127
+ result: pillarStatus
128
+ },
129
+ report: {
130
+ level: ReportLevel.INFO,
131
+ message: `光柱检查完成,${pillarStatus.online}/${pillarStatus.total} 在线`
132
+ },
133
+ timestamp: new Date().toISOString(),
134
+ version: '1.0'
135
+ });
136
+
137
+ // 发送最终响应
138
+ await gateway.sendCommandResponse({
139
+ type: MessageType.COMMAND_RESPONSE,
140
+ requestRef,
141
+ status: CommandStatus.COMPLETED,
142
+ result: {
143
+ deviceType: 'controller',
144
+ deviceId: this.deviceId,
145
+ commandCode: 'HealthCheck',
146
+ operationType: OperationType.READ,
147
+ data: {
148
+ overallHealth: 'good',
149
+ checksPerformed: 4,
150
+ checksPassed: 4,
151
+ details: {
152
+ switchStatus,
153
+ config,
154
+ syncStatus,
155
+ pillarStatus
156
+ }
157
+ }
158
+ },
159
+ report: {
160
+ level: ReportLevel.INFO,
161
+ message: '健康检查完成,所有系统正常'
162
+ },
163
+ executionTime: Date.now() - startTime,
164
+ timestamp: new Date().toISOString(),
165
+ version: '1.0'
166
+ });
167
+
168
+ } catch (error) {
169
+ // 错误处理
170
+ await gateway.sendProgressUpdate({
171
+ type: MessageType.PROGRESS_UPDATE,
172
+ requestRef,
173
+ status: ProgressStatus.FAILED,
174
+ phase: 'error',
175
+ progress: (currentStep / totalSteps) * 100,
176
+ sourceType: 'SYSTEM',
177
+ report: {
178
+ level: ReportLevel.ERROR,
179
+ message: '健康检查失败',
180
+ code: 'HEALTH_CHECK_ERROR',
181
+ data: {
182
+ error: error.message,
183
+ step: currentStep
184
+ }
185
+ },
186
+ timestamp: new Date().toISOString(),
187
+ version: '1.0'
188
+ });
189
+
190
+ // 发送失败响应
191
+ await gateway.sendCommandResponse({
192
+ type: MessageType.COMMAND_RESPONSE,
193
+ requestRef,
194
+ status: CommandStatus.FAILED,
195
+ report: {
196
+ level: ReportLevel.ERROR,
197
+ message: error.message,
198
+ code: 'HEALTH_CHECK_FAILED'
199
+ },
200
+ timestamp: new Date().toISOString(),
201
+ version: '1.0'
202
+ });
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ ## Batch 命令进度更新
209
+
210
+ ### 批量设置颜色示例
211
+
212
+ ```typescript
213
+ class BatchCommandHandler {
214
+ async executeBatchCommand(command: CommandMessage, gateway: GatewayConnection) {
215
+ const { deviceId, parameters } = command.command;
216
+ const devices = this.parseDeviceRange(deviceId as string); // "1-10,20-30"
217
+ const total = devices.length;
218
+ let completed = 0;
219
+ let failed = 0;
220
+ const results = [];
221
+
222
+ for (const device of devices) {
223
+ try {
224
+ // 执行单个设备命令
225
+ const result = await this.executeOnDevice(device, parameters);
226
+ completed++;
227
+
228
+ // 发送进度更新
229
+ await gateway.sendProgressUpdate({
230
+ type: MessageType.PROGRESS_UPDATE,
231
+ requestRef: command.requestRef,
232
+ status: ProgressStatus.IN_PROGRESS,
233
+ phase: 'executing',
234
+ progress: Math.round((completed / total) * 100),
235
+ sourceType: 'COMMAND',
236
+ command: {
237
+ commandType: CommandType.SIMPLE,
238
+ commandCode: command.command.commandCode,
239
+ deviceType: command.command.deviceType,
240
+ deviceId: device,
241
+ operationType: command.command.operationType,
242
+ result: result
243
+ },
244
+ report: {
245
+ level: ReportLevel.INFO,
246
+ message: `设备 ${device} 执行成功`,
247
+ data: {
248
+ deviceId: device,
249
+ completed,
250
+ total,
251
+ failed
252
+ }
253
+ },
254
+ timestamp: new Date().toISOString(),
255
+ version: '1.0'
256
+ });
257
+
258
+ results.push({ deviceId: device, success: true, result });
259
+
260
+ } catch (error) {
261
+ failed++;
262
+
263
+ // 发送错误进度更新
264
+ await gateway.sendProgressUpdate({
265
+ type: MessageType.PROGRESS_UPDATE,
266
+ requestRef: command.requestRef,
267
+ status: ProgressStatus.IN_PROGRESS,
268
+ phase: 'executing',
269
+ progress: Math.round(((completed + failed) / total) * 100),
270
+ sourceType: 'COMMAND',
271
+ command: {
272
+ commandType: CommandType.SIMPLE,
273
+ commandCode: command.command.commandCode,
274
+ deviceType: command.command.deviceType,
275
+ deviceId: device,
276
+ operationType: command.command.operationType,
277
+ result: { error: error.message }
278
+ },
279
+ report: {
280
+ level: ReportLevel.WARNING,
281
+ message: `设备 ${device} 执行失败: ${error.message}`,
282
+ code: 'DEVICE_EXECUTION_FAILED',
283
+ data: {
284
+ deviceId: device,
285
+ error: error.message,
286
+ completed,
287
+ total,
288
+ failed
289
+ }
290
+ },
291
+ timestamp: new Date().toISOString(),
292
+ version: '1.0'
293
+ });
294
+
295
+ results.push({ deviceId: device, success: false, error: error.message });
296
+ }
297
+ }
298
+
299
+ // 发送最终响应
300
+ const finalStatus = failed === 0 ? CommandStatus.COMPLETED :
301
+ failed < total ? CommandStatus.COMPLETED :
302
+ CommandStatus.FAILED;
303
+
304
+ await gateway.sendCommandResponse({
305
+ type: MessageType.COMMAND_RESPONSE,
306
+ requestRef: command.requestRef,
307
+ status: finalStatus,
308
+ result: {
309
+ deviceType: command.command.deviceType,
310
+ deviceId: command.command.deviceId,
311
+ commandCode: command.command.commandCode,
312
+ operationType: command.command.operationType,
313
+ data: {
314
+ summary: `批量命令执行完成`,
315
+ targetCount: total,
316
+ successCount: completed,
317
+ failureCount: failed,
318
+ results: results
319
+ }
320
+ },
321
+ report: {
322
+ level: failed === 0 ? ReportLevel.INFO : ReportLevel.WARNING,
323
+ message: `批量命令完成: ${completed}/${total} 成功`,
324
+ data: {
325
+ successRate: Math.round((completed / total) * 100)
326
+ }
327
+ },
328
+ executionTime: Date.now() - startTime,
329
+ timestamp: new Date().toISOString(),
330
+ version: '1.0'
331
+ });
332
+ }
333
+ }
334
+ ```
335
+
336
+ ## Program 上传进度更新
337
+
338
+ ### 程序上传完整流程
339
+
340
+ ```typescript
341
+ class ProgramUploadHandler {
342
+ async handleProgramUpload(program: ProgramMessage, gateway: GatewayConnection) {
343
+ const { parameters } = program.command;
344
+ const context: ProgramContext = {
345
+ taskId: parameters.taskId,
346
+ programId: parameters.programId,
347
+ programName: parameters.programName,
348
+ programNumber: parameters.programNumber,
349
+ programType: parameters.programType
350
+ };
351
+
352
+ try {
353
+ // Phase 1: 下载
354
+ await this.reportProgress(gateway, program.requestRef, {
355
+ phase: ProgressPhase.DOWNLOAD,
356
+ progress: 0,
357
+ sourceType: 'SYSTEM',
358
+ context,
359
+ report: {
360
+ level: ReportLevel.INFO,
361
+ message: '开始下载节目文件...'
362
+ }
363
+ });
364
+
365
+ const fileData = await this.downloadFile(
366
+ parameters.downloadUrl,
367
+ (progress) => {
368
+ this.reportProgress(gateway, program.requestRef, {
369
+ phase: ProgressPhase.DOWNLOAD,
370
+ progress: progress * 0.3, // 下载占30%
371
+ sourceType: 'SYSTEM',
372
+ context,
373
+ report: {
374
+ level: ReportLevel.DEBUG,
375
+ message: `下载进度: ${Math.round(progress * 100)}%`,
376
+ data: {
377
+ bytesDownloaded: progress * parameters.fileSize,
378
+ totalBytes: parameters.fileSize
379
+ }
380
+ }
381
+ });
382
+ }
383
+ );
384
+
385
+ // Phase 2: 解压
386
+ await this.reportProgress(gateway, program.requestRef, {
387
+ phase: ProgressPhase.DECOMPRESS,
388
+ progress: 30,
389
+ sourceType: 'SYSTEM',
390
+ context,
391
+ report: {
392
+ level: ReportLevel.INFO,
393
+ message: '正在解压文件...'
394
+ }
395
+ });
396
+
397
+ const extractedFiles = await this.extractFiles(fileData);
398
+
399
+ // Phase 3: 预处理
400
+ await this.reportProgress(gateway, program.requestRef, {
401
+ phase: ProgressPhase.PREPROCESS,
402
+ progress: 40,
403
+ sourceType: 'SYSTEM',
404
+ context,
405
+ report: {
406
+ level: ReportLevel.INFO,
407
+ message: '正在预处理节目内容...'
408
+ }
409
+ });
410
+
411
+ // 检查设备配置
412
+ const deviceConfig = await this.readDeviceConfig();
413
+ await this.reportProgress(gateway, program.requestRef, {
414
+ phase: ProgressPhase.PREPROCESS,
415
+ progress: 45,
416
+ sourceType: 'COMMAND',
417
+ context,
418
+ command: {
419
+ commandType: CommandType.SIMPLE,
420
+ commandCode: 'READ_DISPLAY_CONFIG',
421
+ deviceType: 'display',
422
+ deviceId: 1,
423
+ operationType: OperationType.READ,
424
+ result: deviceConfig
425
+ },
426
+ report: {
427
+ level: ReportLevel.INFO,
428
+ message: '设备配置读取完成'
429
+ }
430
+ });
431
+
432
+ // Phase 4: 创建帧
433
+ await this.reportProgress(gateway, program.requestRef, {
434
+ phase: ProgressPhase.FRAMES,
435
+ progress: 50,
436
+ sourceType: 'SYSTEM',
437
+ context,
438
+ report: {
439
+ level: ReportLevel.INFO,
440
+ message: '正在创建节目帧...'
441
+ }
442
+ });
443
+
444
+ const frames = await this.createFrames(
445
+ extractedFiles,
446
+ deviceConfig,
447
+ (frameProgress) => {
448
+ this.reportProgress(gateway, program.requestRef, {
449
+ phase: ProgressPhase.FRAMES,
450
+ progress: 50 + frameProgress * 30, // 创建帧占30%
451
+ sourceType: 'SYSTEM',
452
+ context,
453
+ report: {
454
+ level: ReportLevel.DEBUG,
455
+ message: `帧创建进度: ${Math.round(frameProgress * 100)}%`
456
+ }
457
+ });
458
+ }
459
+ );
460
+
461
+ // Phase 5: 上传到设备
462
+ await this.reportProgress(gateway, program.requestRef, {
463
+ phase: ProgressPhase.UPLOAD,
464
+ progress: 80,
465
+ sourceType: 'SYSTEM',
466
+ context,
467
+ report: {
468
+ level: ReportLevel.INFO,
469
+ message: '正在上传到设备...'
470
+ }
471
+ });
472
+
473
+ const uploadResult = await this.uploadToDevice(
474
+ frames,
475
+ parameters.programNumber,
476
+ (uploadProgress) => {
477
+ this.reportProgress(gateway, program.requestRef, {
478
+ phase: ProgressPhase.UPLOAD,
479
+ progress: 80 + uploadProgress * 15, // 上传占15%
480
+ sourceType: 'COMMAND',
481
+ context,
482
+ command: {
483
+ commandType: CommandType.SIMPLE,
484
+ commandCode: 'WRITE_PROGRAM_DATA',
485
+ deviceType: 'storage',
486
+ deviceId: 1,
487
+ operationType: OperationType.WRITE,
488
+ result: {
489
+ blocksWritten: Math.round(uploadProgress * 1000),
490
+ totalBlocks: 1000
491
+ }
492
+ },
493
+ report: {
494
+ level: ReportLevel.DEBUG,
495
+ message: `上传进度: ${Math.round(uploadProgress * 100)}%`
496
+ }
497
+ });
498
+ }
499
+ );
500
+
501
+ // Phase 6: 统计
502
+ await this.reportProgress(gateway, program.requestRef, {
503
+ phase: ProgressPhase.STATS,
504
+ progress: 95,
505
+ sourceType: 'COMMAND',
506
+ context,
507
+ command: {
508
+ commandType: CommandType.SIMPLE,
509
+ commandCode: 'FINALIZE_PROGRAM',
510
+ deviceType: 'controller',
511
+ deviceId: 1,
512
+ operationType: OperationType.WRITE,
513
+ result: uploadResult
514
+ },
515
+ report: {
516
+ level: ReportLevel.INFO,
517
+ message: '正在完成节目激活...'
518
+ }
519
+ });
520
+
521
+ const stats = await this.gatherStatistics(uploadResult);
522
+
523
+ // 完成
524
+ await this.reportProgress(gateway, program.requestRef, {
525
+ phase: ProgressPhase.STATS,
526
+ progress: 100,
527
+ status: ProgressStatus.COMPLETED,
528
+ sourceType: 'SYSTEM',
529
+ context,
530
+ report: {
531
+ level: ReportLevel.INFO,
532
+ message: '节目上传完成',
533
+ data: stats
534
+ }
535
+ });
536
+
537
+ // 发送最终响应
538
+ await gateway.sendProgramResponse({
539
+ type: MessageType.PROGRAM_RESPONSE,
540
+ requestRef: program.requestRef,
541
+ status: CommandStatus.COMPLETED,
542
+ context,
543
+ report: {
544
+ level: ReportLevel.INFO,
545
+ message: '程序上传并激活成功'
546
+ },
547
+ executionTime: Date.now() - startTime,
548
+ timestamp: new Date().toISOString(),
549
+ version: '1.0'
550
+ });
551
+
552
+ } catch (error) {
553
+ // 错误处理
554
+ await this.reportProgress(gateway, program.requestRef, {
555
+ phase: this.currentPhase,
556
+ progress: this.currentProgress,
557
+ status: ProgressStatus.FAILED,
558
+ sourceType: 'SYSTEM',
559
+ context,
560
+ report: {
561
+ level: ReportLevel.ERROR,
562
+ message: '程序上传失败',
563
+ code: 'UPLOAD_FAILED',
564
+ data: {
565
+ error: error.message,
566
+ phase: this.currentPhase
567
+ }
568
+ }
569
+ });
570
+
571
+ await gateway.sendProgramResponse({
572
+ type: MessageType.PROGRAM_RESPONSE,
573
+ requestRef: program.requestRef,
574
+ status: CommandStatus.FAILED,
575
+ context,
576
+ report: {
577
+ level: ReportLevel.ERROR,
578
+ message: error.message,
579
+ code: 'PROGRAM_UPLOAD_FAILED'
580
+ },
581
+ timestamp: new Date().toISOString(),
582
+ version: '1.0'
583
+ });
584
+ }
585
+ }
586
+
587
+ private async reportProgress(
588
+ gateway: GatewayConnection,
589
+ requestRef: string,
590
+ update: Partial<ProgressUpdateMessage>
591
+ ) {
592
+ await gateway.sendMessage({
593
+ type: MessageType.PROGRESS_UPDATE,
594
+ requestRef,
595
+ status: ProgressStatus.IN_PROGRESS,
596
+ timestamp: new Date().toISOString(),
597
+ version: '1.0',
598
+ ...update
599
+ } as ProgressUpdateMessage);
600
+ }
601
+ }
602
+ ```
603
+
604
+ ## 错误处理最佳实践
605
+
606
+ ### 优雅的错误恢复
607
+
608
+ ```typescript
609
+ class ErrorHandlingExample {
610
+ async executeWithRetry(command: CommandMessage, gateway: GatewayConnection) {
611
+ const maxRetries = 3;
612
+ let attempt = 0;
613
+
614
+ while (attempt < maxRetries) {
615
+ try {
616
+ attempt++;
617
+
618
+ // 尝试执行
619
+ const result = await this.execute(command);
620
+
621
+ // 成功
622
+ await gateway.sendProgressUpdate({
623
+ type: MessageType.PROGRESS_UPDATE,
624
+ requestRef: command.requestRef,
625
+ status: ProgressStatus.COMPLETED,
626
+ phase: 'completed',
627
+ progress: 100,
628
+ sourceType: 'SYSTEM',
629
+ report: {
630
+ level: ReportLevel.INFO,
631
+ message: '执行成功',
632
+ data: { attempts: attempt }
633
+ },
634
+ timestamp: new Date().toISOString(),
635
+ version: '1.0'
636
+ });
637
+
638
+ return result;
639
+
640
+ } catch (error) {
641
+ // 发送警告
642
+ await gateway.sendProgressUpdate({
643
+ type: MessageType.PROGRESS_UPDATE,
644
+ requestRef: command.requestRef,
645
+ status: ProgressStatus.IN_PROGRESS,
646
+ phase: 'retrying',
647
+ progress: (attempt / maxRetries) * 100,
648
+ sourceType: 'SYSTEM',
649
+ report: {
650
+ level: ReportLevel.WARNING,
651
+ message: `执行失败,正在重试 (${attempt}/${maxRetries})`,
652
+ code: 'EXECUTION_RETRY',
653
+ data: {
654
+ attempt,
655
+ maxRetries,
656
+ error: error.message
657
+ }
658
+ },
659
+ timestamp: new Date().toISOString(),
660
+ version: '1.0'
661
+ });
662
+
663
+ if (attempt >= maxRetries) {
664
+ // 最终失败
665
+ await gateway.sendProgressUpdate({
666
+ type: MessageType.PROGRESS_UPDATE,
667
+ requestRef: command.requestRef,
668
+ status: ProgressStatus.FAILED,
669
+ phase: 'failed',
670
+ progress: 100,
671
+ sourceType: 'SYSTEM',
672
+ report: {
673
+ level: ReportLevel.ERROR,
674
+ message: '执行失败,已达最大重试次数',
675
+ code: 'MAX_RETRIES_EXCEEDED',
676
+ data: {
677
+ attempts: attempt,
678
+ lastError: error.message
679
+ }
680
+ },
681
+ timestamp: new Date().toISOString(),
682
+ version: '1.0'
683
+ });
684
+
685
+ throw error;
686
+ }
687
+
688
+ // 等待后重试
689
+ await this.delay(1000 * attempt);
690
+ }
691
+ }
692
+ }
693
+ }
694
+ ```
695
+
696
+ ## 性能监控示例
697
+
698
+ ```typescript
699
+ class PerformanceMonitor {
700
+ async executeWithMonitoring(command: CommandMessage, gateway: GatewayConnection) {
701
+ const metrics = {
702
+ startTime: Date.now(),
703
+ memoryBefore: process.memoryUsage(),
704
+ phases: new Map<string, number>()
705
+ };
706
+
707
+ // 执行并监控每个阶段
708
+ const phases = ['init', 'process', 'finalize'];
709
+
710
+ for (const phase of phases) {
711
+ const phaseStart = Date.now();
712
+
713
+ await this.executePhase(phase, command);
714
+
715
+ const phaseDuration = Date.now() - phaseStart;
716
+ metrics.phases.set(phase, phaseDuration);
717
+
718
+ // 报告性能指标
719
+ await gateway.sendProgressUpdate({
720
+ type: MessageType.PROGRESS_UPDATE,
721
+ requestRef: command.requestRef,
722
+ status: ProgressStatus.IN_PROGRESS,
723
+ phase,
724
+ progress: ((phases.indexOf(phase) + 1) / phases.length) * 100,
725
+ sourceType: 'SYSTEM',
726
+ report: {
727
+ level: ReportLevel.DEBUG,
728
+ message: `阶段 ${phase} 完成`,
729
+ data: {
730
+ phaseDuration,
731
+ totalDuration: Date.now() - metrics.startTime,
732
+ memoryUsage: process.memoryUsage()
733
+ }
734
+ },
735
+ timestamp: new Date().toISOString(),
736
+ version: '1.0'
737
+ });
738
+ }
739
+ }
740
+ }
741
+ ```
742
+
743
+ ## 总结
744
+
745
+ Progress Update 机制提供了灵活而强大的进度报告能力:
746
+
747
+ 1. **统一的进度模型** - 适用于各种长时间操作
748
+ 2. **结构化日志** - 不同级别的详细信息
749
+ 3. **设备操作追踪** - 记录每个设备操作
750
+ 4. **错误恢复机制** - 优雅处理错误和重试
751
+ 5. **性能监控** - 实时性能指标
752
+
753
+ 正确使用 Progress Update 可以:
754
+ - 提供更好的用户体验
755
+ - 便于问题诊断和调试
756
+ - 实现精细的操作控制
757
+ - 支持操作的暂停和恢复