@microi.net/cli 6.0.8 → 6.1.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 (119) hide show
  1. package/.codebuddy-plugin/marketplace.json +2 -2
  2. package/.codebuddy-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/.workbuddy-plugin/marketplace.json +2 -2
  5. package/.workbuddy-plugin/plugin.json +1 -1
  6. package/assets/build-meta.json +5 -5
  7. package/cordis.patch.yml +1 -1
  8. package/package.json +1 -1
  9. package/scripts/mcp-server.js +96 -96
  10. package/scripts/microi-cli.js +1 -1
  11. package/scripts/microi-skills.meta.json +309 -309
  12. package/skills/.microi-skills-version.json +2 -2
  13. package/skills/.progressive-disclosure-manifest.json +13 -13
  14. package/skills/README.md +287 -287
  15. package/skills/ai-engine/SKILL.md +273 -273
  16. package/skills/ai-engine/references/ai-employees.md +48 -48
  17. package/skills/ai-engine/references/self-hosted-digital-human.md +59 -59
  18. package/skills/ai-platform-governance/references/progressive-01-/345/212/237/350/203/275/345/274/200/345/205/263.md +2 -2
  19. package/skills/app-store/SKILL.md +3 -3
  20. package/skills/business-blueprint/SKILL.md +193 -193
  21. package/skills/datasource-engine/SKILL.md +93 -93
  22. package/skills/dos-orm/SKILL.md +105 -105
  23. package/skills/dos-orm/references/api-reference.md +229 -229
  24. package/skills/email-engine/SKILL.md +81 -81
  25. package/skills/email-engine/references/v8-email.md +34 -34
  26. package/skills/job-engine/SKILL.md +176 -176
  27. package/skills/message-notification/SKILL.md +156 -156
  28. package/skills/message-notification/references/contracts.md +102 -102
  29. package/skills/microi/SKILL.md +14 -14
  30. package/skills/microi-ai-app-auth.js +1 -1
  31. package/skills/microi-ai-application/SKILL.md +115 -115
  32. package/skills/microi-ai-application/references/frontend-baseline.md +164 -164
  33. package/skills/microi-client-frontend/SKILL.md +19 -19
  34. package/skills/microi-client-frontend/references/progressive-01-3-/345/212/250/346/200/201/346/214/211/351/222/256/347/263/273/347/273/237.md +10 -10
  35. package/skills/microi-client-frontend/references/progressive-02-8-/350/277/220/350/241/214/346/227/266/351/253/230/351/242/221/345/235/221/345/244/215/347/233/230.md +10 -10
  36. package/skills/microi-client-frontend/references/progressive-03-vue3-/345/211/215/347/253/257/345/276/256/346/234/215/345/212/241/345/256/277/344/270/273/350/247/204/345/210/231.md +10 -10
  37. package/skills/microi-codex/SKILL.md +130 -130
  38. package/skills/microi-codex-installer/SKILL.md +233 -233
  39. package/skills/microi-datasource-mapping/SKILL.md +122 -122
  40. package/skills/microi-db-schema/SKILL.md +175 -175
  41. package/skills/microi-db-schema/references/core-tables.md +695 -695
  42. package/skills/microi-db-schema/references/form-component-options.md +256 -256
  43. package/skills/microi-db-schema/references/schema-overview.md +202 -202
  44. package/skills/microi-db-schema/references/schema.md +646 -646
  45. package/skills/microi-db-schema/references/table-catalog.md +1599 -1599
  46. package/skills/microi-deployment/SKILL.md +260 -258
  47. package/skills/microi-deployment/references/deployment-matrix.md +109 -109
  48. package/skills/microi-docs-coverage/SKILL.md +133 -133
  49. package/skills/microi-docs-coverage/references/capability-map.md +91 -91
  50. package/skills/microi-form-engine/SKILL.md +338 -338
  51. package/skills/microi-form-engine/references/component-catalog.md +218 -218
  52. package/skills/microi-form-engine/references/data-source-events.md +124 -124
  53. package/skills/microi-left-right-layout/SKILL.md +141 -141
  54. package/skills/microi-microservice/SKILL.md +353 -348
  55. package/skills/microi-microservice/references/runtime-delivery.md +282 -282
  56. package/skills/microi-solution-quotation/SKILL.md +78 -78
  57. package/skills/microi-sso/SKILL.md +102 -102
  58. package/skills/microi-sso/references/acceptance.md +51 -51
  59. package/skills/microi-sso/references/configuration-and-security.md +53 -53
  60. package/skills/microi-sso/references/inbound.md +53 -53
  61. package/skills/microi-sso/references/outbound.md +43 -43
  62. package/skills/microi-system-delivery/SKILL.md +18 -16
  63. package/skills/microi-system-delivery/references/context-quality.md +3 -3
  64. package/skills/microi-system-delivery/references/progressive-01-/346/240/207/345/207/206/345/267/245/344/275/234/346/265/201.md +11 -11
  65. package/skills/microi-system-delivery/references/progressive-02-/350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/345/277/205/351/241/273/350/246/206/347/233/226/347/232/204/345/235/221.md +12 -8
  66. package/skills/microi-system-delivery/references/progressive-03-/345/256/211/345/205/250/344/270/216/350/267/250/347/253/257/351/252/214/346/224/266.md +8 -8
  67. package/skills/module-engine/SKILL.md +297 -297
  68. package/skills/module-engine/references/module-config.md +204 -204
  69. package/skills/ocr-engine/SKILL.md +113 -113
  70. package/skills/page-engine/SKILL.md +24 -24
  71. package/skills/page-engine/references/progressive-01-/346/211/200/346/234/211/347/273/204/344/273/266/347/261/273/345/236/213.md +10 -10
  72. package/skills/page-engine/references/progressive-02-/347/211/210/346/234/254/345/216/206/345/217/262-/345/271/266/345/217/221/344/277/235/345/255/230/344/270/216/345/233/236/346/273/232.md +12 -12
  73. package/skills/performance-testing/SKILL.md +227 -227
  74. package/skills/print-engine/SKILL.md +259 -259
  75. package/skills/production-readonly-audit/SKILL.md +41 -41
  76. package/skills/report-engine/SKILL.md +83 -83
  77. package/skills/search-engine/SKILL.md +75 -75
  78. package/skills/spider-engine/SKILL.md +190 -190
  79. package/skills/system-observability/SKILL.md +264 -264
  80. package/skills/system-observability/references/memory-incident-triage.md +77 -77
  81. package/skills/translate-engine/SKILL.md +140 -140
  82. package/skills/ui-design/assets/templates/MCI-DESIGN.md +206 -206
  83. package/skills/ui-design/references/design-pattern-library.md +184 -184
  84. package/skills/ui-design/references/mci-design-contract.md +163 -163
  85. package/skills/ui-design/references/motion-and-media.md +78 -78
  86. package/skills/ui-design/references/product-flow-recipes.md +94 -94
  87. package/skills/uniapp-mall-assets/SKILL.md +176 -176
  88. package/skills/unity-integration/SKILL.md +178 -178
  89. package/skills/unity-integration/references/ai-app-delivery.md +119 -119
  90. package/skills/unity-integration/references/sdk-api.md +82 -82
  91. package/skills/unity-integration/references/toolbox-migration.md +66 -66
  92. package/skills/unity-integration/references/webgl-hosting.md +57 -57
  93. package/skills/v8-cache-pattern/SKILL.md +320 -320
  94. package/skills/v8-debugging/SKILL.md +284 -284
  95. package/skills/v8-explorer-tree/SKILL.md +228 -228
  96. package/skills/v8-file-upload/SKILL.md +1 -1
  97. package/skills/v8-file-upload/references/cdn-alias-repair.md +13 -13
  98. package/skills/v8-formengine-http/SKILL.md +238 -238
  99. package/skills/v8-frontend-events/references/bluetooth-print-api.md +135 -135
  100. package/skills/v8-frontend-events/references/bluetooth-print.md +258 -258
  101. package/skills/v8-image-processing/SKILL.md +190 -190
  102. package/skills/v8-image-processing/references/api-reference.md +623 -623
  103. package/skills/v8-mongodb/SKILL.md +201 -201
  104. package/skills/v8-mq-mqtt/references/mqtt-production.md +352 -352
  105. package/skills/v8-saas-multi-tenant/SKILL.md +305 -305
  106. package/skills/v8-sql-query/SKILL.md +302 -302
  107. package/skills/v8-tcp-integration/SKILL.md +158 -158
  108. package/skills/v8-template-engine/SKILL.md +167 -167
  109. package/skills/v8-utilities/SKILL.md +104 -104
  110. package/skills/v8-utilities/references/client-api-index.md +143 -143
  111. package/skills/v8-utilities/references/platform-http-routes.md +83 -83
  112. package/skills/v8-utilities/references/server-api-index.md +188 -188
  113. package/skills/v8-workflow/references/workflow-configuration.md +49 -49
  114. package/skills/vision-engine/SKILL.md +160 -160
  115. package/skills/vision-engine/references/architecture-and-acceptance.md +194 -194
  116. package/skills/workspace-conventions/SKILL.md +15 -3
  117. package/skills/workspace-conventions/references/progressive-01-/347/211/210/346/234/254/346/233/264/346/226/260/346/227/245/345/277/227/344/277/235/346/212/244/350/247/204/345/210/231-/345/274/272/345/210/266.md +33 -33
  118. package/skills/workspace-conventions/references/progressive-02-microi-net-api-/346/234/254/345/234/260/345/220/257/345/212/250/347/272/246/345/256/232.md +34 -34
  119. package/skills/workspace-conventions/references/progressive-03-cli-/344/270/216-ide-/346/217/222/344/273/266/351/224/231/347/211/210/345/205/261/345/255/230/347/272/246/345/256/232.md +6 -6
@@ -1,158 +1,158 @@
1
- ---
2
- name: v8-tcp-integration
3
- description: Microi 后端 V8 TCP 原始字节集成规范。用于通过 V8.Tcp.Send/SendAsync/SendAndReceive/SendAndReceiveAsync 连接网络小票机、串口服务器、PLC 或其它 TCP 设备,处理 Byte/Base64/Hex/Text 载荷、GBK/GB18030、超时、响应、幂等与出站安全。
4
- ---
5
-
6
- > **Microi吾码基础规范(强制):** 任何 AI 模型与宿主每次新建或接续吾码任务,先完整读取 `../workspace-conventions/SKILL.md`,必须执行版本播报、`@microi.net/cli` 后台自动升级、Skills/MCP 同步和进度播报。安装与诊断读取 `../microi-codex-installer/SKILL.md`;更新失败延后重试,不阻断当前工作。
7
-
8
- # Microi V8 TCP 原始字节集成
9
-
10
- 使用后端 `V8.Tcp` 完成一次性 TCP 连接、原始字节写入和可选的有界响应读取。典型场景是 RAW/JetDirect 9100 网络小票机、串口服务器和 PLC;具体协议帧、校验码与打印业务仍由接口引擎编排。
11
-
12
- 文档维护时,只在 `microi.doc/docs/doc/v8-engine/v8-server.md` 原位更新后端 API;不要新建重复页面,也不要手工维护英文文档。改变公共契约时同步后端源码/测试、Microi.Client Monaco 定义、Microi.Agent 类型与生成知识、AI Skill 镜像。
13
-
14
- ## 先判断是否适用
15
-
16
- | 需求 | 选择 |
17
- |---|---|
18
- | 后端向设备 TCP 端口发送原始字节 | `V8.Tcp` |
19
- | HTTP/HTTPS API | `V8.Http`,不要用 TCP 重写 HTTP |
20
- | RabbitMQ/MQTT | `V8.MQ` 或 MQTT 引擎 |
21
- | 浏览器/5+App 蓝牙或 SPP 打印 | 前端 `V8.Print`,读取 `v8-frontend-events/references/bluetooth-print.md` |
22
- | 设备原始 TCP 上报并保持连接等待应答 | API 宿主可选的 `TcpIngressRulesJson` 入站监听;固定租户与接口引擎,协议帧交给接口引擎处理 |
23
- | TLS、任意协议、可由 V8 动态开端口、自定义连接池 | 当前不提供;单独评估安全边界和传输实现 |
24
-
25
- 平台已经提供可复用原子能力后,打印模板、设备选择、订单状态、幂等和审计优先写在接口引擎/表单事件;不要为单个打印业务再写 C# Controller。
26
-
27
- ## API 容器内的原始 TCP 入站
28
-
29
- `V8.Tcp` 仍然仅是出站客户端。设备只能填主机/IP 与端口、不能发送 HTTP 请求路径时,可在同一个 `Microi.net.Api` 进程启用独立原始 TCP 监听;HTTP 的 `1052` 等端口不变,TCP 必须使用另一个端口。入口由主租户 `sys_osclients.TcpIngressEnable`、`TcpIngressPort` 与 `TcpIngressRulesJson` 配置:启用状态空值/1 允许加载完整规则、0 明确关闭;端口留空时容器内默认 `1885`;规则留空不监听、坏规则只使 TCP `Faulted`。规则 JSON 不得含 `enabled` 或 `listenPort`。运行中每约 30 秒独立回查主库开关,设 `0` 后下一轮关闭 TCP 监听与会话,HTTP 继续;从 `0` 改回空值/1、或修改端口/规则/Key/CIDR,不会热重绑,必须手工重启现有 API 容器。只允许主租户管理员维护,配置不得进入 `V8.OsClientModel` 投影。
30
-
31
- 入站配置固定 `osClient`、`apiEngineKey`、来源 CIDR、帧头/帧尾、U16BE 长度字段、CRC16/XMODEM 与请求/响应关联区间;独立的 `TcpIngressPort` 固定容器内监听端口。设备报文绝不能决定租户或调用哪个接口引擎。来源网段优先使用已核实的 IPv4 窄网段;确实无法按来源 IP 限制时,只有在规则 JSON 中显式设置 `allowAnySource:true` 且 `allowedCidrs` **仅**为 `["0.0.0.0/0"]` 才允许任意 IPv4 来源。省略/设为 `false` 时,`/0` 不合法;`/0` 也不能与其它网段混写。这是高风险例外,不是默认推荐或设备鉴权。监听器以固定 `_InvokeType=Server` 内部调用已启用的接口引擎,启动时必须验证目标 `StopHttp=1`、`AllowAnonymous=0`,否则 TCP 局部失败关闭、不监听,以免匿名 HTTP 绕过 TCP 来源约束;HTTP API 保持运行。接口引擎接收 `frameHex`,把原始应答字节的十六进制放在 `Data.ResponseFrameHex`;协议明确的失败应答即使业务 `Code=0` 也需要回传。没有合法应答、校验不通过或超时则关闭连接,不制造成功回执。拆包、粘包、连续心跳均须逐帧处理并在原连接回包。
32
-
33
- 上线顺序:先部署并启动新 API,确认 `sys_config.ServerVersion >= 7.6.16.0` 且旧 `MqttEnable` 空值已迁为 `0`,再通过商城安装/更新 SaaS 包并发布带 `NullValue=1` 的前端;物理迁移不会自动更新旧租户 UI 元数据。新 TCP 包未安装时空规则不监听、HTTP 继续。然后明确设主租户 `TcpIngressEnable=0` 且暂留空规则;核实旧 HTTP 地址没有合法调用方,或先迁移它们,再**仅对目标接口**设置 `StopHttp=1`、`AllowAnonymous=0` 并验证匿名 HTTP 被拒;最后填写完整 TCP 规则、设 `TcpIngressEnable=1`、配置宿主端口及来源策略并重启同一容器。旧 HTTP 仍被使用时不得直接切换。其它厂商的接口与端口不作改动,但 API 容器重启后要逐条回归。
34
-
35
- 启用前优先限制来源网段与云安全组,设置帧长、连接数和空闲时间上限;CRC、设备号都不是身份认证。经 CLB 时核对后端实际看到的源 IP,且当前不解析 Proxy Protocol v2 报头。全网例外必须有业务接口内的设备身份/授权校验、幂等与异常连接监控;如果协议本身没有不可伪造的设备凭据,应明确记录剩余风险,并在能识别来源时收窄规则及云侧放行。Docker 在同一个 API service 显式增加如 `19011:1885/tcp`(宿主机对外端口:容器内端口)的映射;不要把 `/apiengine/...` URL、HTTP 的 `80/1052` 或 `V8.Tcp.Send` 当作设备端 TCP 监听。新执行的在线一键安装器会在 `61600+` 连续宿主端口段末尾追加 MQTT/TCP 映射;离线默认宿主 `7010/7011`,都映射至 API 容器 `1883/1885` 并尝试放行宿主机防火墙。窄来源方案仍需云安全组/CLB 人工限源;已有 Compose 不会自动补映射,SaaS 内部端口改变后须同步 Compose。TCP 配置、引擎安全位或端口失败时仅 TCP 状态为 `Faulted`,HTTP 仍可健康;验收必须确认 TCP `Listening` 状态/监听日志、端口探测和合法心跳应答,再核对设备数据。只连上端口不能证明已回 ACK;当前没有对外的 TCP 状态 HTTP 端点,不能把 HTTP 健康当成 TCP 就绪。配置、回环测试、设备联调的详细步骤见官网中文后端 V8 页面;本地回环不等于客户真机已联网。
36
-
37
- ## API 契约
38
-
39
- | 方法 | 行为 |
40
- |---|---|
41
- | `V8.Tcp.Send({...})` | 连接、发送、关闭,返回 `DosResult` |
42
- | `await V8.Tcp.SendAsync({...})` | 当前请求内异步发送 |
43
- | `V8.Tcp.SendAndReceive({...})` | 发送后读取响应,再关闭 |
44
- | `await V8.Tcp.SendAndReceiveAsync({...})` | 当前请求内异步发送并读取响应 |
45
-
46
- 必填目标参数:
47
-
48
- - `Host`:主机名或 IP;只允许主机,不传 `tcp://` URL。
49
- - `Port`:1-65535。
50
-
51
- 发送内容必须且只能选择一组:
52
-
53
- - `Bytes`(别名 `RawBytes`、`ByteArray`):每项为 0-255 的整数。
54
- - `ByteBase64`(别名 `BytesBase64`、`Base64`)。
55
- - `Hex`:允许空格、`0x`、`-`、`:`、逗号和下划线分隔。
56
- - `Text`:按 `Encoding` 编码。默认 `utf-8`,还支持 `ascii`、`gb18030`、`gbk/gb2312`、UTF-16/UTF-32 大小端。
57
-
58
- 边界参数:
59
-
60
- | 参数 | 默认 | 范围 |
61
- |---|---:|---:|
62
- | `ConnectTimeout` | 10 秒 | 1-120 秒 |
63
- | `SendTimeout` | 10 秒 | 1-120 秒 |
64
- | `ReceiveTimeout` | 3 秒 | 1-120 秒 |
65
- | `MaxReceiveBytes` | 65536 | 1-1048576 |
66
- | `NoDelay` | `true` | 布尔值 |
67
-
68
- 单次发送最多 4 MiB。`Send` 成功数据为 `{BytesSent, RemoteEndPoint}`。收发方法另有 `BytesReceived`、`RawBytes`、`ByteBase64`、`Hex`、`ReceiveEndReason`、`Truncated`;`ReceiveEndReason` 为 `RemoteClosed`、`Timeout` 或 `MaxReceiveBytes`。
69
-
70
- ## 实现流程
71
-
72
- ### 1. 固定并授权设备目标
73
-
74
- 从 SaaS 可信配置或受行权限保护的设备表读取 `Host`、`Port`,按当前用户/门店/租户决定可用设备,再与精确白名单比较。禁止这样写:
75
-
76
- ```javascript
77
- // 错误:匿名或普通调用者可扫描后端可达内网。
78
- return V8.Tcp.Send({
79
- Host: V8.Param.Host,
80
- Port: V8.Param.Port,
81
- Hex: V8.Param.Hex
82
- });
83
- ```
84
-
85
- ### 2. 形成一个完整帧
86
-
87
- ESC/POS、Modbus TCP 或设备私有协议的命令、正文和校验码应先合成一个完整字节载荷。不要为了拼帧而打开多次连接;包含中文和控制命令时,优先在可信后端/上游把完整帧编码为 `Bytes`、`ByteBase64` 或 `Hex`。
88
-
89
- ```javascript
90
- var result = V8.Tcp.Send({
91
- Host: '192.168.1.88', // 示例;生产从可信配置读取
92
- Port: 9100,
93
- Bytes: [
94
- 27, 64, // ESC @ 初始化
95
- 77, 105, 99, 114, 111, 105, 10,
96
- 10, 10,
97
- 29, 86, 0 // GS V 0 切纸
98
- ],
99
- ConnectTimeout: 5,
100
- SendTimeout: 5
101
- });
102
- if (result.Code !== 1) return result;
103
- ```
104
-
105
- 只有纯文本时可使用打印机常见编码:
106
-
107
- ```javascript
108
- var result = await V8.Tcp.SendAsync({
109
- Host: '192.168.1.88',
110
- Port: 9100,
111
- Text: '吾码小票\n合计:12.00\n\n',
112
- Encoding: 'gb18030'
113
- });
114
- if (result.Code !== 1) return result;
115
- ```
116
-
117
- ### 3. 需要协议响应时显式收取
118
-
119
- ```javascript
120
- var result = V8.Tcp.SendAndReceive({
121
- Host: '192.168.1.20',
122
- Port: 4001,
123
- Hex: '01 03 00 00 00 02 C4 0B',
124
- ReceiveTimeout: 3,
125
- MaxReceiveBytes: 4096
126
- });
127
- if (result.Code !== 1) return result;
128
-
129
- var bytes = result.Data.RawBytes;
130
- var hex = result.Data.Hex;
131
- ```
132
-
133
- 接收超时是整段接收的总时间。已收到部分数据后超时会返回成功和已有数据,并标记 `ReceiveEndReason='Timeout'`;未收到任何字节则失败。协议必须知道响应长度或结束条件,不能把超时默认当作完整帧。
134
-
135
- ### 4. 分开判断写入、设备执行和实物结果
136
-
137
- - `Code=1` 只表示字节已写入 TCP 连接。
138
- - 设备协议回执可证明设备接受/处理到哪一步,但仍不一定证明机械动作完成。
139
- - “小票已打印”需要打印机状态、设备回执或实物/硬件验收证据。
140
-
141
- 打印不是天然幂等。不确定失败时自动重试可能重复出纸;需要可靠打印时使用业务打印单号、设备回执、状态机以及 Job/MQ/outbox,且重试策略必须识别“尚未发送”和“结果未知”。
142
-
143
- ## 安全与运行约束
144
-
145
- 1. TCP 不经过 `V8.Http` 的 SSRF 防护。容器网络策略/防火墙只放行目标设备网段和端口;匿名接口不得暴露任意目标。
146
- 2. 不把票据正文、设备口令、原始帧和响应秘密写入日志;日志只记录脱敏设备标识、业务单号、字节数、耗时和错误分类。
147
- 3. `SendAsync` 只是在当前请求内等待 I/O,不能替代后台任务。不要遗留未等待 Promise、`setTimeout` 或 `Task.Run`。
148
- 4. 每次调用都会创建并关闭连接;不能假设设备会保持会话状态。
149
- 5. Docker 内的 `localhost` 指容器自身。验收前从实际后端容器验证到设备 IP/端口的路由和出站策略。
150
- 6. 载荷、超时和响应均有硬上限;不要通过拆成无限循环规避限制。
151
-
152
- ## 修改公共能力时的同步门禁
153
-
154
- - 源码:`Microi.Server/Microi.V8Engine/Extend/Tcp/V8Tcp.cs` 与 `V8Extend.cs`。
155
- - 测试:真实 Jint 注入、Byte/Base64/Hex/Text、回环收发、超时/上限/非法参数。
156
- - 编辑器:`Microi.Client/.../v8-api-server-definitions.js` 与 `Microi.Agent/src/editor/typingsManager.ts`。
157
- - 文档与知识:官网中文后端 V8 页面、`microi.skills/README.md`、`v8-utilities` 索引、`Microi.AI/Resource` 镜像和向量资源列表。
158
- - 验收:目标测试、后端构建、精确重启与健康检查、独立 TCP 回环;真实打印机出纸必须单独报告,不能用回环测试替代。
1
+ ---
2
+ name: v8-tcp-integration
3
+ description: Microi 后端 V8 TCP 原始字节集成规范。用于通过 V8.Tcp.Send/SendAsync/SendAndReceive/SendAndReceiveAsync 连接网络小票机、串口服务器、PLC 或其它 TCP 设备,处理 Byte/Base64/Hex/Text 载荷、GBK/GB18030、超时、响应、幂等与出站安全。
4
+ ---
5
+
6
+ > **Microi吾码基础规范(强制):** 任何 AI 模型与宿主每次新建或接续吾码任务,先完整读取 `../workspace-conventions/SKILL.md`,必须执行版本播报、`@microi.net/cli` 后台自动升级、Skills/MCP 同步和进度播报。安装与诊断读取 `../microi-codex-installer/SKILL.md`;更新失败延后重试,不阻断当前工作。
7
+
8
+ # Microi V8 TCP 原始字节集成
9
+
10
+ 使用后端 `V8.Tcp` 完成一次性 TCP 连接、原始字节写入和可选的有界响应读取。典型场景是 RAW/JetDirect 9100 网络小票机、串口服务器和 PLC;具体协议帧、校验码与打印业务仍由接口引擎编排。
11
+
12
+ 文档维护时,只在 `microi.doc/docs/doc/v8-engine/v8-server.md` 原位更新后端 API;不要新建重复页面,也不要手工维护英文文档。改变公共契约时同步后端源码/测试、Microi.Client Monaco 定义、Microi.Agent 类型与生成知识、AI Skill 镜像。
13
+
14
+ ## 先判断是否适用
15
+
16
+ | 需求 | 选择 |
17
+ |---|---|
18
+ | 后端向设备 TCP 端口发送原始字节 | `V8.Tcp` |
19
+ | HTTP/HTTPS API | `V8.Http`,不要用 TCP 重写 HTTP |
20
+ | RabbitMQ/MQTT | `V8.MQ` 或 MQTT 引擎 |
21
+ | 浏览器/5+App 蓝牙或 SPP 打印 | 前端 `V8.Print`,读取 `v8-frontend-events/references/bluetooth-print.md` |
22
+ | 设备原始 TCP 上报并保持连接等待应答 | API 宿主可选的 `TcpIngressRulesJson` 入站监听;固定租户与接口引擎,协议帧交给接口引擎处理 |
23
+ | TLS、任意协议、可由 V8 动态开端口、自定义连接池 | 当前不提供;单独评估安全边界和传输实现 |
24
+
25
+ 平台已经提供可复用原子能力后,打印模板、设备选择、订单状态、幂等和审计优先写在接口引擎/表单事件;不要为单个打印业务再写 C# Controller。
26
+
27
+ ## API 容器内的原始 TCP 入站
28
+
29
+ `V8.Tcp` 仍然仅是出站客户端。设备只能填主机/IP 与端口、不能发送 HTTP 请求路径时,可在同一个 `Microi.net.Api` 进程启用独立原始 TCP 监听;HTTP 的 `1052` 等端口不变,TCP 必须使用另一个端口。入口由主租户 `sys_osclients.TcpIngressEnable`、`TcpIngressPort` 与 `TcpIngressRulesJson` 配置:启用状态空值/1 允许加载完整规则、0 明确关闭;端口留空时容器内默认 `1885`;规则留空不监听、坏规则只使 TCP `Faulted`。规则 JSON 不得含 `enabled` 或 `listenPort`。运行中每约 30 秒独立回查主库开关,设 `0` 后下一轮关闭 TCP 监听与会话,HTTP 继续;从 `0` 改回空值/1、或修改端口/规则/Key/CIDR,不会热重绑,必须手工重启现有 API 容器。只允许主租户管理员维护,配置不得进入 `V8.OsClientModel` 投影。
30
+
31
+ 入站配置固定 `osClient`、`apiEngineKey`、来源 CIDR、帧头/帧尾、U16BE 长度字段、CRC16/XMODEM 与请求/响应关联区间;独立的 `TcpIngressPort` 固定容器内监听端口。设备报文绝不能决定租户或调用哪个接口引擎。来源网段优先使用已核实的 IPv4 窄网段;确实无法按来源 IP 限制时,只有在规则 JSON 中显式设置 `allowAnySource:true` 且 `allowedCidrs` **仅**为 `["0.0.0.0/0"]` 才允许任意 IPv4 来源。省略/设为 `false` 时,`/0` 不合法;`/0` 也不能与其它网段混写。这是高风险例外,不是默认推荐或设备鉴权。监听器以固定 `_InvokeType=Server` 内部调用已启用的接口引擎,启动时必须验证目标 `StopHttp=1`、`AllowAnonymous=0`,否则 TCP 局部失败关闭、不监听,以免匿名 HTTP 绕过 TCP 来源约束;HTTP API 保持运行。接口引擎接收 `frameHex`,把原始应答字节的十六进制放在 `Data.ResponseFrameHex`;协议明确的失败应答即使业务 `Code=0` 也需要回传。没有合法应答、校验不通过或超时则关闭连接,不制造成功回执。拆包、粘包、连续心跳均须逐帧处理并在原连接回包。
32
+
33
+ 上线顺序:先部署并启动新 API,确认 `sys_config.ServerVersion >= 7.6.16.0` 且旧 `MqttEnable` 空值已迁为 `0`,再通过商城安装/更新 SaaS 包并发布带 `NullValue=1` 的前端;物理迁移不会自动更新旧租户 UI 元数据。新 TCP 包未安装时空规则不监听、HTTP 继续。然后明确设主租户 `TcpIngressEnable=0` 且暂留空规则;核实旧 HTTP 地址没有合法调用方,或先迁移它们,再**仅对目标接口**设置 `StopHttp=1`、`AllowAnonymous=0` 并验证匿名 HTTP 被拒;最后填写完整 TCP 规则、设 `TcpIngressEnable=1`、配置宿主端口及来源策略并重启同一容器。旧 HTTP 仍被使用时不得直接切换。其它厂商的接口与端口不作改动,但 API 容器重启后要逐条回归。
34
+
35
+ 启用前优先限制来源网段与云安全组,设置帧长、连接数和空闲时间上限;CRC、设备号都不是身份认证。经 CLB 时核对后端实际看到的源 IP,且当前不解析 Proxy Protocol v2 报头。全网例外必须有业务接口内的设备身份/授权校验、幂等与异常连接监控;如果协议本身没有不可伪造的设备凭据,应明确记录剩余风险,并在能识别来源时收窄规则及云侧放行。Docker 在同一个 API service 显式增加如 `19011:1885/tcp`(宿主机对外端口:容器内端口)的映射;不要把 `/apiengine/...` URL、HTTP 的 `80/1052` 或 `V8.Tcp.Send` 当作设备端 TCP 监听。新执行的在线一键安装器会在 `61600+` 连续宿主端口段末尾追加 MQTT/TCP 映射;离线默认宿主 `7010/7011`,都映射至 API 容器 `1883/1885` 并尝试放行宿主机防火墙。窄来源方案仍需云安全组/CLB 人工限源;已有 Compose 不会自动补映射,SaaS 内部端口改变后须同步 Compose。TCP 配置、引擎安全位或端口失败时仅 TCP 状态为 `Faulted`,HTTP 仍可健康;验收必须确认 TCP `Listening` 状态/监听日志、端口探测和合法心跳应答,再核对设备数据。只连上端口不能证明已回 ACK;当前没有对外的 TCP 状态 HTTP 端点,不能把 HTTP 健康当成 TCP 就绪。配置、回环测试、设备联调的详细步骤见官网中文后端 V8 页面;本地回环不等于客户真机已联网。
36
+
37
+ ## API 契约
38
+
39
+ | 方法 | 行为 |
40
+ |---|---|
41
+ | `V8.Tcp.Send({...})` | 连接、发送、关闭,返回 `DosResult` |
42
+ | `await V8.Tcp.SendAsync({...})` | 当前请求内异步发送 |
43
+ | `V8.Tcp.SendAndReceive({...})` | 发送后读取响应,再关闭 |
44
+ | `await V8.Tcp.SendAndReceiveAsync({...})` | 当前请求内异步发送并读取响应 |
45
+
46
+ 必填目标参数:
47
+
48
+ - `Host`:主机名或 IP;只允许主机,不传 `tcp://` URL。
49
+ - `Port`:1-65535。
50
+
51
+ 发送内容必须且只能选择一组:
52
+
53
+ - `Bytes`(别名 `RawBytes`、`ByteArray`):每项为 0-255 的整数。
54
+ - `ByteBase64`(别名 `BytesBase64`、`Base64`)。
55
+ - `Hex`:允许空格、`0x`、`-`、`:`、逗号和下划线分隔。
56
+ - `Text`:按 `Encoding` 编码。默认 `utf-8`,还支持 `ascii`、`gb18030`、`gbk/gb2312`、UTF-16/UTF-32 大小端。
57
+
58
+ 边界参数:
59
+
60
+ | 参数 | 默认 | 范围 |
61
+ |---|---:|---:|
62
+ | `ConnectTimeout` | 10 秒 | 1-120 秒 |
63
+ | `SendTimeout` | 10 秒 | 1-120 秒 |
64
+ | `ReceiveTimeout` | 3 秒 | 1-120 秒 |
65
+ | `MaxReceiveBytes` | 65536 | 1-1048576 |
66
+ | `NoDelay` | `true` | 布尔值 |
67
+
68
+ 单次发送最多 4 MiB。`Send` 成功数据为 `{BytesSent, RemoteEndPoint}`。收发方法另有 `BytesReceived`、`RawBytes`、`ByteBase64`、`Hex`、`ReceiveEndReason`、`Truncated`;`ReceiveEndReason` 为 `RemoteClosed`、`Timeout` 或 `MaxReceiveBytes`。
69
+
70
+ ## 实现流程
71
+
72
+ ### 1. 固定并授权设备目标
73
+
74
+ 从 SaaS 可信配置或受行权限保护的设备表读取 `Host`、`Port`,按当前用户/门店/租户决定可用设备,再与精确白名单比较。禁止这样写:
75
+
76
+ ```javascript
77
+ // 错误:匿名或普通调用者可扫描后端可达内网。
78
+ return V8.Tcp.Send({
79
+ Host: V8.Param.Host,
80
+ Port: V8.Param.Port,
81
+ Hex: V8.Param.Hex
82
+ });
83
+ ```
84
+
85
+ ### 2. 形成一个完整帧
86
+
87
+ ESC/POS、Modbus TCP 或设备私有协议的命令、正文和校验码应先合成一个完整字节载荷。不要为了拼帧而打开多次连接;包含中文和控制命令时,优先在可信后端/上游把完整帧编码为 `Bytes`、`ByteBase64` 或 `Hex`。
88
+
89
+ ```javascript
90
+ var result = V8.Tcp.Send({
91
+ Host: '192.168.1.88', // 示例;生产从可信配置读取
92
+ Port: 9100,
93
+ Bytes: [
94
+ 27, 64, // ESC @ 初始化
95
+ 77, 105, 99, 114, 111, 105, 10,
96
+ 10, 10,
97
+ 29, 86, 0 // GS V 0 切纸
98
+ ],
99
+ ConnectTimeout: 5,
100
+ SendTimeout: 5
101
+ });
102
+ if (result.Code !== 1) return result;
103
+ ```
104
+
105
+ 只有纯文本时可使用打印机常见编码:
106
+
107
+ ```javascript
108
+ var result = await V8.Tcp.SendAsync({
109
+ Host: '192.168.1.88',
110
+ Port: 9100,
111
+ Text: '吾码小票\n合计:12.00\n\n',
112
+ Encoding: 'gb18030'
113
+ });
114
+ if (result.Code !== 1) return result;
115
+ ```
116
+
117
+ ### 3. 需要协议响应时显式收取
118
+
119
+ ```javascript
120
+ var result = V8.Tcp.SendAndReceive({
121
+ Host: '192.168.1.20',
122
+ Port: 4001,
123
+ Hex: '01 03 00 00 00 02 C4 0B',
124
+ ReceiveTimeout: 3,
125
+ MaxReceiveBytes: 4096
126
+ });
127
+ if (result.Code !== 1) return result;
128
+
129
+ var bytes = result.Data.RawBytes;
130
+ var hex = result.Data.Hex;
131
+ ```
132
+
133
+ 接收超时是整段接收的总时间。已收到部分数据后超时会返回成功和已有数据,并标记 `ReceiveEndReason='Timeout'`;未收到任何字节则失败。协议必须知道响应长度或结束条件,不能把超时默认当作完整帧。
134
+
135
+ ### 4. 分开判断写入、设备执行和实物结果
136
+
137
+ - `Code=1` 只表示字节已写入 TCP 连接。
138
+ - 设备协议回执可证明设备接受/处理到哪一步,但仍不一定证明机械动作完成。
139
+ - “小票已打印”需要打印机状态、设备回执或实物/硬件验收证据。
140
+
141
+ 打印不是天然幂等。不确定失败时自动重试可能重复出纸;需要可靠打印时使用业务打印单号、设备回执、状态机以及 Job/MQ/outbox,且重试策略必须识别“尚未发送”和“结果未知”。
142
+
143
+ ## 安全与运行约束
144
+
145
+ 1. TCP 不经过 `V8.Http` 的 SSRF 防护。容器网络策略/防火墙只放行目标设备网段和端口;匿名接口不得暴露任意目标。
146
+ 2. 不把票据正文、设备口令、原始帧和响应秘密写入日志;日志只记录脱敏设备标识、业务单号、字节数、耗时和错误分类。
147
+ 3. `SendAsync` 只是在当前请求内等待 I/O,不能替代后台任务。不要遗留未等待 Promise、`setTimeout` 或 `Task.Run`。
148
+ 4. 每次调用都会创建并关闭连接;不能假设设备会保持会话状态。
149
+ 5. Docker 内的 `localhost` 指容器自身。验收前从实际后端容器验证到设备 IP/端口的路由和出站策略。
150
+ 6. 载荷、超时和响应均有硬上限;不要通过拆成无限循环规避限制。
151
+
152
+ ## 修改公共能力时的同步门禁
153
+
154
+ - 源码:`Microi.Server/Microi.V8Engine/Extend/Tcp/V8Tcp.cs` 与 `V8Extend.cs`。
155
+ - 测试:真实 Jint 注入、Byte/Base64/Hex/Text、回环收发、超时/上限/非法参数。
156
+ - 编辑器:`Microi.Client/.../v8-api-server-definitions.js` 与 `Microi.Agent/src/editor/typingsManager.ts`。
157
+ - 文档与知识:官网中文后端 V8 页面、`microi.skills/README.md`、`v8-utilities` 索引、`Microi.AI/Resource` 镜像和向量资源列表。
158
+ - 验收:目标测试、后端构建、精确重启与健康检查、独立 TCP 回环;真实打印机出纸必须单独报告,不能用回环测试替代。