8.7 KiB
iXserverLoopEnv:模拟闭环测试环境
在 FG-W11-ICON-DEV 一台机器上把五个角色跑起来,让一条 IG 消息从入站到第三方回复、再回到 IG 全程走真 HTTP。
方案与取舍见 iXserver 仓库的 docs/构建模拟闭环测试环境.html。
| 角色 | 端口 | 来源 |
|---|---|---|
| ABP(授权 + 消息模板) | https 44332 | C:\Projects\HKTBAbp 发布到 run\abp |
| iXserver API(IIS Express) | 8081,WebSocket 33346 | C:\Projects\iXserver 整解决方案编译后拷到 run\ixserver |
| 第三方 chatbot 客户端 | 5056 | iXserver\Tools\ThirdPartyChatbotTestClient |
| IG 后端模拟 | 5070 | iXserver\Tools\IgMockServer |
| SCRM 客服系统模拟 | 5080 | iXserver\Tools\ScrmMockServer |
| 闭环观察台(只读,泳道时序图) | 5090 | iXserver\Tools\LoopConsole |
所有端口只绑本机。iXserver 的旧接口和 WebSocket 没有鉴权,绝不能对外开放 8081 / 33346。
这个仓库装什么
只装「环境」:loop.ps1、config\、db\、tools\、scenarios\、deployed.json。
程序本身不在这里——两个模拟服务的代码在 iXserver 的 Tools\(它们模拟的是 iXserver 自己的协议,
要和协议改动同一个提交);编译产物、日志、上传文件在被忽略的 run\。
以 Mac 上的 ~/projects/iXserverLoopEnv 为准,用 remote-dev-box 的 sync.sh 推到 winbox 的
C:\Projects\iXserverLoopEnv。提交在 Mac 上做,winbox 上只跑。
第一次
.\loop.ps1 reset-abp -Init # iCONAbpFX 拷完后:换 setsail secret 与 admin 密码,留底
.\loop.ps1 deploy # 编译 iXserver 整解决方案 + 发布 ABP(慢)
.\loop.ps1 reset # 建 iXserverLoop:EDMX 建表 → FeatureTest 种子 → loop_patch,留底
.\loop.ps1 up
之后日常:
.\loop.ps1 status
.\loop.ps1 deploy -Only ixserver # 改了 iXserver 代码
.\loop.ps1 deploy -Only ixserver -ConfigOnly # 只改了 config\ixserver\overrides.psd1
.\loop.ps1 reset -FromBackup # 库回到干净状态(秒级)
.\loop.ps1 logs -Only ixserver -Tail 100
.\loop.ps1 down
场景
scenarios\ 下每个脚本独立可跑,通过退出 0、失败退出 1 并打印两侧记录。前提是 up 后各角色都健康。
观察台在跑时,每次跑完(通过或失败)都会生成一份场景报告:这次的时序图、iXserver 内部步骤、逐步断言、部署版本,
存成 run\reports\<开始时间>-<场景>-<PASS|FAIL>.html(单文件,离线可开,不进 git)。
.\loop.ps1 reports 列出最近的,观察台 http://127.0.0.1:5090/reports/ 里也能点开。加 -NoReport 只断言不出报告(省几秒)。
新写场景照 S1 / S8 点源 scenarios\_lib.ps1:Start-LoopRun → 每个断言 Add-LoopStep → Save-LoopReport。
.\scenarios\s1-ig-text-echo.ps1 # IG 文本 → iXserver → 第三方 chatbot echo → IG 收到
.\scenarios\s2-auth-ip-whitelist.ps1 # IP 白名单:token 端点 + send-txt 经真 IIS 放行 / 拒绝、可信代理的 XFF 规则;临时改 oauth_client 与 Web.config,结束还原,约 2~3 分钟
.\scenarios\s5-ig-handoff.ps1 # 机器人工单 → SCRM 开工 + 客服上线 → 下一条:echo 在前、问句在后 → 点 Yes → 新人工工单 → 客服回复 → 旧单迟到回复 409 → 下班
.\scenarios\s8-human-chain.ps1 # SCRM 开工 → 新 IG 用户 → 人工工单推送 → 指派 / 回复 → IG 收到 → 结束 → 下班
S5 依赖 epro_ig_demo 的 DisconnectChatbotFlowSetting 已打开(db\ixserver\loop_patch.sql 第 3 节;没 reset 过的库要单独执行那一段),
问句按钮标题跟 ABP 模板走,模板改过时用 -YesTitle 指定。
跑的时候开着观察台 http://127.0.0.1:5090,每一跳和状态变化会实时画成泳道时序图;?ticket=<工单号> 只看一张。
epro_ig_demo 常开条款同意(db\ixserver\loop_patch.sql 第 3 节的 T_and_C_Setting):
新 IG 用户的第一句话会被条款拦下,三个场景都先调 _lib.ps1 的 Complete-LoopTnC 走完「条款 → 同意 → 选语言 → 问候」。
staging 的 IG 条款组缺 Agree 按钮(漏了 Line 问候里的「Agreement Button (Line IG)」);闭环 ABP 在
db\abp\loop_patch.sql 第 3 节补上了,这一处与 staging 不同。改过这个补丁要 .\loop.ps1 reset-abp -Init 重新打并留底。
S5 / S8 结束时(失败也一样)会把服务号切回机器人、在线人数归零,所以几个场景先后跑互不影响;要停在人工状态看页面加 -KeepShift。
从 Mac 看几个页面用 SSH 本地端口转发:
ssh -N -L 5056:127.0.0.1:5056 -L 5070:127.0.0.1:5070 -L 5080:127.0.0.1:5080 -L 5090:127.0.0.1:5090 FG-W11-ICON-DEV
几个容易踩的点
- 库是 iXserverLoop,不是 iXsererTest。 FeatureTest 每个方法都 drop 重建 iXsererTest, 反过来闭环 API 的连接池连着它会让 FeatureTest 无限卡在删库上。
- API 从
run\ixserver跑,不从API\源码目录跑。 编译 FeatureTest 会刷新API\bin里的模块 dll, 正在跑的站点会被回收、甚至换成依赖不全的版本。 reset把建库与loop_patch.sql绑在一起。 种子里有真格式的 FB token 与 api.commas.hk 等真实 webhook, 补丁把它们全换成假值 / 黑洞,并在末尾自检;不提供「只建不补」。OAuth_Authority必须逐字等于本地 ABP 签出 token 的iss。 IdentityServer4 没设 IssuerUri, iss 取请求的 Host,所以全链路统一用https://localhost:44332,换成 127.0.0.1 就全部 401。- 签名密钥不在库里,在 ABP 进程工作目录的
tempkey.jwk。deploy 删掉仓库里那把开发密钥, 首次up时 ABP 自己生成一把,留存到run\abp-key\,之后重新部署沿用同一把。 - 备份在 SQL 实例的默认备份目录(
*.loop.bak),不在run\backup\:SQL 服务账号对C:\Projects不一定有写权限。 - 进程用 WMI(Win32_Process.Create)起,不用 Start-Process:经 SSH 起的进程会随会话一起被杀。
pid 记在
run\pids\,down按进程树杀。 - VS Code 的自动端口转发会抢闭环端口。 在 winbox 上用 VS Code Remote-SSH 连 Mac 时,它从终端输出里认
localhost:端口,然后在 winbox 本机占住同一个端口转发回 Mac,闭环角色就报「端口被 Code 占着」。 Mac 的~/.vscode-server/data/Machine/settings.json已设remote.autoForwardPorts=false、remote.restoreForwardedPorts=false;已经转发出去的要在 VS Code「端口」面板里停掉。 - WMI 起的进程只有系统环境变量。
TEMP是C:\Windows\TEMP,ASP.NET 编译临时目录也会退回系统目录, 没写权限,首个请求就 500。loop.ps1给每个角色设了TEMP/TMP指到run\data\temp, 并在 Web.config 的<compilation>上写tempDirectory。 - ABP 的 HTTPS 证书用的是 IIS Express 自带的 localhost 证书(LocalMachine\My,到 2030 年,已在当前用户受信任根里)。 winbox 的 ASP.NET dev 证书 2026-05 已过期;用 IIS Express 这张,iXserver(.NET Framework)连 ABP 不用另外信任、也不弹框。
- ABP 的各个 DbContext 按名字找连接串,找不到退回
Default,而仓库appsettings.json的Default指向公司内网的库。appsettings.Loop.json把所有连接串都盖成本机 iCONAbpFX。 - PowerShell 5.1 的两个坑已经在
loop.ps1里绕开:原生命令往 stderr 写一行就抛异常(统一走Invoke-Native);Get-Content默认按 GBK 读无 BOM 的 UTF-8(拷配置用Copy-Item,脚本文件一律带 BOM)。 - iXserver 的主日志在
run\ixserver\Log\{Debug,Information,Warning,Error}\<日期>\(注入的 ILogger,内部步骤很全,观察台就读它)。run\data\API_Log是静态Logger写的另一份,几乎是空的,别看它下结论。排查先看Log\Error。deploy的 robocopy 排除了Log/Logs,重新部署不会清掉日志。 deployed.json记录每次部署时两个源码仓库的 commit 与未提交文件。闭环结果离开「当时部署的是哪个版本」没法解读, 跑场景的记录里引用它。注意 winbox 上 iXserver 仓库的 HEAD 不随sync.sh前进(只推文件),commit字段可能停在很久以前,以uncommitted清单和 Mac 上的提交为准。
闭环专用凭据(假值,可公开)
见 config\loop.psd1 的 Secrets:setsail 与 FX_App 的 client secret、ABP admin 密码、所有渠道 token 的替身。
staging 的 secret 明文不出现在这个仓库里。