- 在HttpServer中实现了新的API端点:/api/project/open和/api/model/shrinkwrap - 添加了ShrinkwrapModel和OpenProject命令的处理逻辑 - 在PdmsManager中实现了ShrinkwrapModel和OpenProject方法,支持相应请求的处理 - 更新了项目文件以包含新的命令和模型请求类 此更新增强了插件的功能,允许用户通过API进行模型缩减和项目打开操作。
126 lines
8.3 KiB
Markdown
126 lines
8.3 KiB
Markdown
# Tellme PDMS 插件技术架构文档
|
||
|
||
## 1. 项目概述
|
||
- **目标**:为单个 AVEVA PDMS 12.1 SP4 会话提供远程监控与操作能力,实现前端客户端通过 HTTP 接口安全地获取模型状态并下达任务。
|
||
- **运行环境**:.NET Framework 3.5(x86),遵循 PDMS 插件加载约束;前端与插件运行在同一主机,通信默认局限于本地回环接口。
|
||
- **核心原则**:主线程执行 PDMS API、命令模式分离网络与业务、无硬编码数据、兼顾大模型性能与资源占用。
|
||
|
||
## 2. 系统总体架构
|
||
|
||
```mermaid
|
||
graph LR
|
||
A[前端客户端] -->|HTTP/JSON| B[HttpServer]
|
||
B -->|入队| C[SafeQueue]
|
||
C -->|出队| D[PDMS 主线程]
|
||
D --> E[Aveva PDMS API]
|
||
D -->|结果| B
|
||
B -->|响应| A
|
||
```
|
||
|
||
- **入口插件 (`TellmePdmsAddin`)**:实现 `IAddin` 接口,在 PDMS 启动时加载,负责生命周期管理和日志记录。
|
||
- **网络层 (`Network.HttpServer`)**:基于 `System.Net.HttpListener` 自托管 HTTP 服务,路由健康检查与业务接口。
|
||
- **命令层 (`Core.ICommand` 系列)**:每个请求解析为命令对象入队,支持可取消性扩展。
|
||
- **业务层 (`Core.PdmsManager`)**:封装对 `MDB.CurrentMDB`、`Project.CurrentProject`、`DbElement` 等 API 的访问,生成结构化数据。
|
||
- **模型层 (`Models.*`)**:定义 `ModelStatusResponse`、`ProjectInfo`、`ModelStatistics`、`SessionInfo` 等 DTO 以便序列化。
|
||
- **工具层**:提供线程安全队列、日志、序列化和配置扩展点(`Utils` 目录预留)。
|
||
|
||
## 3. 关键技术栈
|
||
|
||
| 分类 | 选型 | 理由 |
|
||
| --- | --- | --- |
|
||
| 插件框架 | `Aveva.ApplicationFramework.IAddin` | 满足 PDMS 扩展规范,允许在主线程注册 Idle 事件 |
|
||
| 语言与平台 | C# + .NET Framework 3.5 (x86) | 与 PDMS 12.1 SP4 兼容,仅 32 位可加载 |
|
||
| 网络通信 | `System.Net.HttpListener` | BCL 自带、无第三方依赖、支持本地自托管 |
|
||
| 序列化 | 自定义轻量 JSON 序列化 | 兼容 .NET 3.5,避免外部依赖,可替换为 `System.Web.Script.Serialization` |
|
||
| 队列实现 | `Queue<T>` + `lock` 封装 | .NET 3.5 无 `ConcurrentQueue`,需手动保证线程安全 |
|
||
| 日志 | 文本文件 (`C:\temp\*.txt`) | 易于部署与排查,可替换为 log4net |
|
||
| 单元测试(预留) | NUnit 2.x | 支持 .NET 3.5,便于未来补充测试 |
|
||
|
||
## 4. 主要模块说明
|
||
|
||
### 4.1 插件入口 `TellmePdmsAddin`
|
||
- `Start(ServiceManager)`:初始化 `HttpServer`、记录启动日志、提示监听端口,并可在此处加载配置或注册 UI 菜单。
|
||
- `Stop()`:释放服务器资源并记录停止日志。
|
||
- `Application.Idle` 事件在其他模块注册,用于在 PDMS 主线程执行命令队列。
|
||
|
||
### 4.2 网络服务 `Network.HttpServer`
|
||
- 构造函数注入端口(默认 9001),仅允许 `http://localhost:<port>/`。
|
||
- `Start()`/`Stop()` 控制 `HttpListener` 生命周期,利用 `BeginGetContext` 异步接受请求。
|
||
- `ProcessRequest` 完成路由分发、CORS 头设置、异常捕获与响应写入。
|
||
- 当前实现的路由:`/health`、`/test`、`/api/status/model`,可扩展 `switch` 和命令解析以支持更多端点。
|
||
|
||
### 4.3 命令抽象 `Core.ICommand`
|
||
- 统一定义 `CommandId`、`CommandType`、`Execute()`,保留 `CanCancel/Cancel()` 扩展位。
|
||
- 推荐为每个 HTTP 接口实现对应命令类,确保执行逻辑仅运行在主线程环境。
|
||
|
||
### 4.4 业务管理 `Core.PdmsManager`
|
||
- 单例模式管理 PDMS 状态查询,避免重复初始化。
|
||
- `GetModelStatus()`:集中调度连接检测、项目信息、模型统计、会话信息。
|
||
- **连接检测**:`MDB.CurrentMDB` 是否返回非空。
|
||
- **项目信息**:通过 `CurrentMDB.GetFirstDB(DbType.Design)` 获取设计库名称、MDS 名称、PDMS 版本。
|
||
- **模型统计**:递归 `DbElement.Members()`,使用 `element.GetActualType().Name` 累加 SITE、ZONE、PIPE 等关键元素数量。
|
||
- **Zone 统计**:遍历 SITE → ZONE 层级,利用 `DbElement.GetValidString(DbAttributeInstance.NAME, ref zoneName)` 采集激活区域名称。
|
||
- **会话信息**:从 `DesignDb.CurrentSession` 读取用户、启动时间,计算持续分钟数。
|
||
- 所有 API 调用包裹 try/catch 并输出调试日志以保证稳定性。
|
||
|
||
## 5. 线程模型
|
||
- HttpListener 线程仅负责解析请求并将命令入队,禁止直接调用 PDMS API。
|
||
- 主线程通过 `Application.Idle` 循环 `SafeQueue.TryDequeue(out ICommand cmd)`,顺序执行。
|
||
- 可在命令执行过程中更新共享的进度字典,以供 `/task/{id}` 查询(待实现)。
|
||
- 长任务需在执行逻辑内部分批处理,并在批次间调用 `GC.Collect()` 控制内存。
|
||
|
||
## 6. HTTP 接口约定
|
||
|
||
| 路径 | 方法 | 描述 | 响应示例 |
|
||
| --- | --- | --- | --- |
|
||
| `/health` | GET | 进程存活检测,返回时间戳与内存占用 | `{ "code":0, "message":"成功", "data":{ "status":"OK", "timestamp":"2025-09-21 12:00:00", "memoryMB":123 } }` |
|
||
| `/test` | GET | 轻量连通性测试,检测是否运行于 PDMS 环境 | `{ "success":true, "data":{ "running":true, "message":"TellmePdms 与 PDMS 连接正常" }, "error":null }` |
|
||
| `/api/status/model` | GET | 返回模型加载状态、项目信息、元素统计、会话信息 | `{ "code":0, "message":"成功", "data":{ ...ModelStatusResponse... } }` |
|
||
|
||
- 响应以 `ApiResponse<T>` 模式封装:`code` 为 0 表示成功,`message` 给出提示,`data` 为业务数据。
|
||
- 自定义错误码示例:`1001` 表示 PDMS 模型未加载,`500` 表示内部异常。
|
||
- 未来规划接口:`POST /command`、`POST /task`、`GET /task/{id}`、`GET /stats`、`POST /export/ifc` 等,可复用命令与模型层。
|
||
|
||
## 7. 数据模型结构
|
||
|
||
### 7.1 `ModelStatusResponse`
|
||
- `ModelLoaded`:PDMS 是否加载模型。
|
||
- `ProjectInfo`:包含 `ProjectName`、`MdsName`、`PdmsVersion`。
|
||
- `ModelStatistics`:`TotalElements`、`ElementCounts (Dictionary<string,int>)`、`ZoneCount`、`ActiveZones`。
|
||
- `SessionInfo`:会话 `UserName`、`StartTime`、`DurationMinutes`。
|
||
|
||
### 7.2 序列化策略
|
||
- 对字典、列表使用定制序列化,确保 .NET 3.5 环境兼容。
|
||
- 日期统一格式 `yyyy-MM-ddTHH:mm:ssZ`,便于前端解析。
|
||
- 主线程执行结束后返回 JSON 字符串,由 HttpServer 写入响应流。
|
||
|
||
## 8. 性能与资源控制
|
||
- **Large Address Aware**:建议为 32 位进程设置 LAA 标志,在 64 位 Windows 上提升可用内存上限至 3 GB。
|
||
- **分批遍历**:对大模型递归时,可按逻辑域(SITE、ZONE)分批处理,减少单次内存占用。
|
||
- **流式响应**:长列表数据可拆分分页或使用压缩(GZip + Base64)后流式传输,避免一次性加载。
|
||
- **GC 管理**:在长任务各阶段主动调用 `GC.Collect()` 并输出当前内存占用,防止内存峰值。
|
||
- **并发限制**:当前设计为单客户端单任务,无任务队列优先级;后续可引入任务管理表实现调度与取消。
|
||
|
||
## 9. 日志与错误处理
|
||
- 插件与服务器分别记录至 `C:\temp\pdms_plugin_log.txt`、`C:\temp\pdms_http_log.txt`。
|
||
- 网络层捕获异常后返回 500 错误并写入日志;业务层捕获异常后返回自定义错误码。
|
||
- 建议引入滚动日志策略(log4net RollingFileAppender)以限制文件大小。
|
||
|
||
## 10. 部署与配置
|
||
1. 以 x86、.NET 3.5 配置编译 `TellmePdmsPluging.sln`。
|
||
2. 将输出 DLL 复制到 PDMS 安装目录,更新 `DesignAddin.xml` 注册插件。
|
||
3. 确保 Windows 防火墙允许本地回环端口 9001;外部访问需额外代理。
|
||
4. 可在 `Config` 目录引入自定义配置(端口、日志路径、批处理大小等),启动时读取。
|
||
5. 部署后通过 `http://localhost:9001/health` 验证服务是否监听。
|
||
|
||
## 11. 后续扩展建议
|
||
- **任务管理**:实现 `/task` 接口与任务表持久化,支持长任务进度查询与取消。
|
||
- **安全加固**:加入鉴权(如基于令牌或双向证书),限制访问来源。
|
||
- **前端工具**:提供 Web 或桌面客户端,集成状态展示与命令触发。
|
||
- **协议升级**:考虑使用 WebSocket 推送进度、MessagePack/Protobuf 提升带宽效率。
|
||
- **监控告警**:将健康检查与日志集成到企业监控平台,追踪内存与任务状态。
|
||
|
||
---
|
||
|
||
本文件概述了 Tellme PDMS 远程控制插件的架构设计、核心组件、关键算法与部署要点,可作为后续开发迭代、测试验证及运维交付的基础参考资料。
|