fix: track live downstream cmpp connections

This commit is contained in:
hectorzhao
2026-07-11 19:16:52 +08:00
parent 76e0417ccf
commit 2fea15ef25
21 changed files with 477 additions and 141 deletions
@@ -211,6 +211,7 @@
1. Gateway 必须监听生产 CMPP 端口 `17890`,作为平台侧 CMPP Server 接收企业客户系统连接;该端口不是 HTTP 健康检查或控制接口。
2. Gateway 必须按企业应用生成的 CMPP 接入参数校验客户 connect/login,包括客户侧企业代码、账号、密码、CMPP 版本、源 IP 白名单、短信接口开关、应用状态、企业状态、连接数上限;客户侧企业代码必须来自 `SmsApplication.cmppEnterpriseCode`,且 `interfaceEnabled=false` 时必须拒绝新的鉴权。已完成 bind 的连接若随后被停用,其后续参数合法 Submit 必须按业务失败记录并通过 Deliver Receipt 回执。Gateway 必须根据 CONNECT `Version` 为每条 TCP 连接独立协商 CMPP2.0/2.1/3.0 解包与响应类型,不得用固定 CMPP3.0 结构解析 CMPP2.0 Submit。
3. 企业应用列表中的 CMPP 连接数和连接状态必须表示客户连接到 Gateway `17890` 的下游 CMPP 会话,不得复用上游 `SmsChannel` 连接状态。Gateway 必须在 bind、CMPP `ACTIVE_TEST`、Submit、Deliver 写入失败等事件时回写应用级连接记录;列表只将最近心跳未超时的会话计为正常连接。超过心跳阈值的会话必须标记为心跳超时/断开,并保留远端 IP、协议版本、建立时间、最后心跳、最后 Submit、最后 Deliver 与断开原因供运营查询。
3. 客户端应用的 IP 白名单必须对 CMPP 下游连接生效;未命中白名单、应用停用、企业停用、密码错误、超过连接数上限时必须拒绝连接并记录系统日志。
4. Gateway 必须维护应用级下游连接状态,回写 applicationId、tenantId、connectionId、currentConnections、desiredConnections、lastHeartbeatAt、lastError,运营端企业应用列表和连接详情必须来自这些真实状态。
5. Gateway 必须实现下游 ActiveTest、Terminate、异常断开处理;断开后连接数和状态必须及时回写。
+1
View File
@@ -1013,6 +1013,7 @@
- 已鉴权且参数合法的 Submit 必须先返回成功 SubmitResp 和平台 Msg_Id;内容不匹配审核模板、签名/报备未通过、余额不足、应用在 bind 后停用、无可用通道、上游 Submit 最终失败时,均须真实创建短信记录、`SmsReceiptRecord``CmppDownstreamDelivery`,并向客户下发 `undelivered/REJECTD` Deliver Receipt,不得仅以 SubmitResp 失败替代回执。
- Gateway 对每次 submit 记录 `submit_received``submit_accepted`/`submit_rejected`;日志可按账号、IP、sequenceId、号码和 messageId 定位,拒绝时包含 NestJS 真实业务原因和 CMPP result,但不包含明文短信正文。
- CMPP 包在进入 handler 前因长度、命令字、读包或 Unpack 失败时,Gateway 记录 `read/unpack packet failed`、远端地址、协议模式、错误类型和原始错误,不得静默断开。
- 企业应用列表和连接详情展示真实下游 CMPP 会话:bind 后当前连接数加一,显示客户 IP、企业代码、CMPP 版本、连接建立时间与最后心跳;连接持续未响应 `ACTIVE_TEST` 超过阈值后转为心跳超时/断开,不能继续显示为正常连接。
### TC-GW-007 CMPP 客户到上游 SMSC 完整闭环
+14
View File
@@ -1559,6 +1559,13 @@ git diff --check
- 已部署生产验证:`cmpp-api``cmpp-gateway`、Nginx、MinIO 均为 activeAPI/Gateway health 均通过。真实认证 API 返回四类待审明细并与总数一致;手机号段第 2 页返回 25 条、总数 516217、`page=2/pageSize=25`,证明页面分页不再依赖 cursor 猜测总页数。
- 浏览器自动化在登录页连接阶段超时,未使用 CAPTCHA 绕过或修改生产数据;登录后页面视觉验收需在下一轮以人工登录或可用浏览器会话补充截图。其余项目以源码、真实 API 和构建结果验收,不能将该未完成的视觉截图记录成已完成。
## 2026-07-11 运营端查询控件与手机号段库重做
- 企业应用、企业签名、企业模板管理页的查询与重置统一为通用 `Button` 操作组:查询提交当前条件到真实 NestJS 列表 API,重置清空条件后重新加载真实列表,不再依赖输入即筛选或状态更新竞态。
- 系统管理的用户管理、手机号段库、报备字段库、系统日志均增加查询和重置;用户与报备字段使用已加载真实数据的显式筛选,系统日志使用已提交筛选条件请求真实日志 API。
- 手机号段库重做为概览、关键词筛选、号段/运营商规则双视图和统一分页工作台。号段和规则均使用 PostgreSQL 返回的 `total/page/pageSize`,不使用静态数组或 cursor 猜测总页数。
- 已执行前端 `npm run build``git diff --check`;已部署生产验证,`cmpp-api``cmpp-gateway`、Nginx、MinIO 均为 activeAPI/Gateway health 通过。生产源码和已构建静态资源均包含新的查询操作组与手机号段工作台样式;手机号段 API 继续返回真实 `total/page/pageSize`
## 2026-07-11 CMPP 业务失败回执闭环
- 修复下游 CMPP 入站的审计缺口:客户已完成 bind、账号可识别且手机号参数合法后,NestJS 会先创建真实 `SmsBatchTask``SmsApiRequest``SmsMessageRecord`,再执行模板、签名/报备、风控和余额校验;不再因模板未报备等业务失败而直接丢弃客户 Submit。
@@ -1566,3 +1573,10 @@ git diff --check
- 同一回执策略覆盖最终通道签名报备失败、无可用路由,以及上游 Submit rejected/timeout 在补发耗尽后的终态失败;失败记录、错误码和错误原因均可在运营端真实短信记录链路查询。
- Gateway 在客户 Submit 成功并建立 messageId-连接映射后立即冲刷该账号 pending 下游投递,避免 API 先创建失败回执时只能等待周期补投。
- 已执行 `npm --prefix api test -- --runInBand send-chain.service.spec.ts`34 项通过)、`npm --prefix api run build``go test ./...`(Gateway 全量通过)。待本轮全量 API/前端构建及生产验证完成后补充最终部署结果。
## 2026-07-11 企业应用下游 CMPP 连接状态修复
- 修复企业应用列表误用上游 `CmppConnectionState` 的问题。新增 PostgreSQL `CmppDownstreamConnection`,一条记录对应一个已鉴权的客户 CMPP TCP bind 会话,按应用保存账号、企业代码、客户端 IP、协议版本、建立时间、最近心跳、最近 Submit、最近 Deliver、断开时间和错误原因。
- Gateway 在客户 bind 成功、`ACTIVE_TEST`、Submit 和下游 Deliver 写入成功/失败时通过真实 NestJS API 回写连接事件;运营端只以该表的 `connected` 会话统计当前连接数,不再把上游通道连接数显示为企业客户连接数。
- API 列表/详情查询会将最近心跳超过 `CMPP_DOWNSTREAM_HEARTBEAT_TIMEOUT_MS`(默认 90 秒)的会话标记为 `heartbeat_timeout`;运营端展示真实客户端 IP、企业代码与最近心跳。移除了不能真正关闭 TCP 连接的运营端“删除连接”伪操作。
- 已执行 `sms-config.service.spec.ts`17 项通过)、Gateway inbound 集成测试(bind 回写连接事件)和 API/前端 build;待全量测试与生产验证完成后补充部署结果。