## 思考: **Laying out the plan** I'm mapping out a detailed remote control system for PDMS 12.1 SP4, covering architecture, technology options, component details, and operational steps. **Pinpointing project specifics** I'm detailing the technology stack, threading model, communication protocols, API design, data models, error handling, build/instructions, security, workflow, monitoring, and the timeline for development.**Laying out the plan** I'm mapping out a detailed remote control system for PDMS 12.1 SP4, covering architecture, technology options, component details, and operational steps. **Pinpointing project specifics** I'm detailing the technology stack, threading model, communication protocols, API design, data models, error handling, build/instructions, security, workflow, monitoring, and the timeline for development.**Laying out the plan** I'm mapping out a detailed remote control system for PDMS 12.1 SP4, covering architecture, technology options, component details, and operational steps. **Pinpointing project specifics** I'm detailing the technology stack, threading model, communication protocols, API design, data models, error handling, build/instructions, security, workflow, monitoring, and the timeline for development. Reasoned for 4m 31s ## 回答 下面是一份可直接交给 PDMS 技术团队实施的 **“单前端 → 单 PDMS 12.1 SP4 会话远程操控”** 完整方案。内容包括总体目标、技术选型、详细架构、接口规范、关键代码骨架、开发与部署步骤、性能与运维要点,以及里程碑计划。 --- ## 1. 项目目标与边界 | 项目维度 | 约束 / 目标 | |---|---| | **软件版本** | AVEVA PDMS 12.1 SP4(32‑bit) | | **并发模型** | 仅一个前端客户端控制一个 PDMS 会话,无多用户并发 | | **模型规模** | 可能包含千万级元件,单次统计/导出任务可持续数十分钟 | | **技术栈硬性限制** | *PDMS 仅支持 .NET 3.5 x86*,高版本框架或 64‑bit DLL 将被拒载 [CSDN Blog](https://blog.csdn.net/u011498594/article/details/101690303) | | **性能目标** | - 交互命令(< 1 s)
- 中型任务(1‑30 s)有进度回报
- 大任务可后台执行,前端可轮询进度 | | **安全范围** | 初期仅限局域网;外网访问通过反向代理 + VPN 后续加固 | --- ## 2. 技术选型概览 | 层次 | 选型 | 说明 | |---|---|---| | **通讯协议** | HTTP/1.1 + JSON/MessagePack(默认)
可选 gRPC‑C 核心库(二期) | HttpListener 属于 BCL,.NET 2.0 起即内置,完全兼容 .NET 3.5 [Microsoft Learn](https://learn.microsoft.com/en-us/dotnet/api/system.net.httplistener?view=net-9.0&utm_source=chatgpt.com) | | **自托管服务器** | `System.Net.HttpListener`(端口 9001,仅监听 `localhost`) | | **PDMS 插件框架** | `IAddin` 接口(须编译为 .NET 3.5 / x86 DLL) [CSDN Blog](https://blog.csdn.net/u011498594/article/details/101690303) | | **线程隔离** | `HttpThread` → **安全队列** → `PDMS 主线程`
(队列用 `Queue + lock` 自行封装,.NET 3.5 无 ConcurrentQueue) | | **序列化** | - 轻量:`System.Web.Script.Serialization`(内置)
- 高性能:`MsgPack‑CLI 0.5.x`(支持 .NET 3.5) | | **日志** | `log4net 1.2.17`(支持 .NET 2.0+) | | **大任务调度** | 简易 `TaskTable` 持久化为 `SQLite` 文件,支持重启后恢复进度 | | **前端** | 任意:Web/Qt/WPF。只需按 REST 协议调用即可。 | --- ## 3. 系统架构与流程 ```mermaid graph LR A[前端 UI (浏览器/桌面)] -- HTTP --> B(HttpListener
PDMS Agent DLL) B -- 入队 --> C[安全队列] C -- 脱队 --> D{PDMS 主线程
Idle/CAF Command} D --> E[PDMS API 调用] D -- 进度/结果 --> B B -- HTTP Response --> A ``` ### 3.1 关键流程 1. **监听**:Agent 在 `Start()` 中启动 `HttpListener`,仅允许 `http://localhost:9001/`。 2. **入队**:收到请求后解析为 `ICommand` 对象写入 `SafeQueue`,立即返回 `202 Accepted + taskId`,前端开始轮询 `/task/{id}`。 3. **执行**:主线程在 `Application.Idle`(或 CAF `Command`) 下轮询 `SafeQueue`,顺序执行命令并周期性写入进度。 4. **结果流式返回**:长列表接口(如统计)使用 *分页或流式分块*,每� GZip 后 Base64 传输,减少内存峰值。 --- ## 4. API 设计(首批 6 个端点) | 方法 | 路径 | 说明 | 返回 | |---|---|---|---| | `GET` | `/health` | 进程存活检测 + 空闲内存 | `{status:"OK", memMB:1234}` | | `POST` | `/command` | 下达即刻命令(<1 s) | `{code:0,data:"OK"}` | | `POST` | `/task` | 启动长任务,返回 `taskId` | `{taskId:"abc123"}` | | `GET` | `/task/{id}` | 查询任务进度 | `{percent:42,state:"RUNNING"}` | | `GET` | `/stats` | 流式统计接口,支持 `queryExpr`, `props[]` | `application/octet-stream`(分块) | | `POST` | `/export/ifc` | 导出 IFC/RVM/CSV | `{downloadUrl:".../ifc.zip"}` | > **统一响应封装**: > ```json > { "code": 0, "msg": "成功", "data": {...} } > ``` > 错误码表放在 `ErrorCodes.cs`,与 CLAUDE.md 中的 `ApiResponse` 结构保持一致。 --- ## 5. 代码骨架(精简示例) ```csharp // AgentAddin.cs (.NET 3.5, x86) [Addin("HttpAgent", Description="PDMS REST Control")] public class HttpAgentAddin : IAddin { private HttpServer _server; public string Description => "PDMS REST Agent"; public string Name => "HttpAgent"; public void Start(ServiceManager sm) { SafeQueue.Init(); // 全局单例 _server = new HttpServer(9001); // 见下 _server.Start(); Application.Idle += OnIdle; // CAF 中同理 } public void Stop() { _server.Dispose(); } void OnIdle(object sender, EventArgs e) { while (SafeQueue.TryDequeue(out ICommand cmd)) { cmd.Execute(); // 必须保证只在主线程调用 PDMS API } } } ``` ```csharp // HttpServer.cs class HttpServer : IDisposable { readonly HttpListener _l = new HttpListener(); public HttpServer(int port) { _l.Prefixes.Add($"http://localhost:{port}/"); } public void Start() { _l.Start(); _l.BeginGetContext(BeginContext, null); } void BeginContext(IAsyncResult ar) { var ctx = _l.EndGetContext(ar); _l.BeginGetContext(BeginContext, null); // 继续监听 ICommand cmd = CmdFactory.Parse(ctx); // JSON => ICommand SafeQueue.Enqueue(cmd); ctx.Response.StatusCode = 202; ctx.Response.Close(); } public void Dispose() => _l.Close(); } ``` ```csharp // SafeQueue.cs (简易线程安全队列 .NET 3.5) static class SafeQueue { static readonly Queue _q = new Queue(); static readonly object _sync = new object(); public static void Enqueue(ICommand c) { lock(_sync) _q.Enqueue(c); } public static bool TryDequeue(out ICommand c) { lock(_sync){ if(_q.Count>0){ c=_q.Dequeue(); return true; } } c=null; return false; } } ``` #### 重点注意 - **严禁在 HttpListener 线程直接操作 PDMS API**;否则 UI 会冻结甚至崩溃。 - 如需长任务取消,可在 `ICommand` 中实现 `CancellationToken` 并于主线程检查。 --- ## 6. 大模型性能优化清单 | 类别 | 操作 | 说明 | |---|---|---| | **内存** | 链接 /LARGEADDRESSAWARE;Win 64‑bit 系统上可让进程地址空间上限从 2 GB 提升到 3 GB (/3GB) [Microsoft Learn](https://learn.microsoft.com/en-us/windows/win32/memory/memory-limits-for-windows-releases) | | **分区遍历** | 让前端传 `ZONE` / `GROUP`,内部执行 `QUERY /*`;尽量避免 `.NET` 侧逐件遍历。 | | **流式返回** | 统计接口按 1 000 条一批序列化 → GZip → Base64;前端 `ReadableStream` 逐块解析并渲染。 | | **后台导出** | `pdms.exe /BATCH macro.pml` 子进程执行 IFC/ISO 批导出,主会话实时返回进度。 | | **资源释放** | 每批次后执行 `GC.Collect()` + `Utilities.Application.DoEvents()`;如内存 > 1.6 GB 发出重启警告。 | --- ## 7. 开发与部署步骤 | 阶段 | 任务 | 负责人 | 预计耗� | |---|---|---|---| | **环境准备** | 安装 VS2013 + .NET 3.5 SP1、PDMS 12.1 SP4 开发版 | 运维 | 1 d | | **Skeleton** | 创建 AgentAddin、SafeQueue、ICommand 抽象、HttpServer | 开发 | 3 d | | **核心命令** | `HealthCmd / ExecCmd / StatsCmd / ExportCmd` | 开发 | 5 d | | **前端 Demo** | 简易 Web 页面(Vue/React 任选)+ 轮询 Task API | 前端 | 3 d | | **任务管理** | `TaskTable` + 进度轮询接口 | 开发 | 2 d | | **日志/异常** | log4net 文件分卷、全局异常捕获 | 开发 | 1 d | | **单元测试** | NUnit + MockPDMS(可选) | QA | 3 d | | **性能测试** | 典型大模型脚本(≥500 MB MDB) | QA | 2 d | | **文档交付** | API Swagger JSON + 部署手册 | 技术写作 | 2 d | | **上线** | 复制 DLL → PDMS 根目录,修改 `DesignAddin.xml`;放行 9001 端口(仅 127.0.0.1)| 运维 | 0.5 d | *总工期预估:约 **3 周**(15 人/日)。* --- ## 8. 交付物清单 1. `HttpAgent.dll` (PDMS 插件,x86, .NET 3.5) 2. `AgentConfig.xml`(端口、日志路径、最大批大小等可配置) 3. 前端示例项目源码 + 打包脚本 4. REST API 文档(Swagger 2.0 / OpenAPI 3.0) 5. 《部署运维手册》:包含 LAA 打开方法、Windows 防火墙配置、日志轮转 6. 《性能基准报告》:不同模型规模下的 CPU/内存曲线与耗时 --- ## 9. 后续演进路线(可选) | 版本 | 规划 | 价值 | |---|---|---| | **v1.1** | 接入 MessagePack + Protobuf Binary Streaming | 带宽降低 50‑80 % | | **v1.2** | WebSocket 通道(长连,实时回推进度) | 减少前端轮询 | | **v2.0** | 升级到 AVEVA E3D(64‑bit & .NET 4.8),换用 ASP.NET Core / Kestrel | 扩展能力 + 长期官方支持 | --- ### 结语 该方案沿用 **“命令队列 + 主线程执行”** 的线程安全模型,摒弃 OWIN/Katana 等高版本依赖,完全兼容 PDMS 12.1 SP4 的 .NET 3.5/x86 运行环境。通过 **分页/流式传输、后台子进程导出、LAA 内存扩展** 等手段,可以在单客户端场景下稳定处理超大模型,同时保留后续迁移到 E3D 的升级路径。 请技术团队严格按上述步骤实施,并在性能测试阶段使用真实项目数据库进行基准,以确保上线后的体验满足设计人员日常使用需求。若在实现过程中遇到 API 调用或资源释放细节问题,建议优先参考 AVEVA 官方 SDK 文档及本文引用资源。祝项目顺利!