如何在 BaSyx AAS SDK 中实现使用外部地址注册 AAS 及其子模型

发布时间 - 2026-01-06 00:00:00    点击率:

本文详解如何在 basyx 1.3 中绕过 `connectedassetadministrationshellmanager` 的内部地址限制,通过组合 `connectedassetadministrationshell`、`aasregistryproxy` 和手动构造 `submodeldescriptor`,确保 aas 与子模型均以**外部可访问地址**(如 `http://some-host:17081/aas`)注册至 aas registry。

在生产级 AAS 部署中,AAS Repository(如 BaSyx AAS Server)常需通过反向代理或容器网络暴露为外部地址(例如 https://aas.example.com/aas),而其内部服务调用则使用本地地址(如 http://localhost:8081/aasServer)。此时,若仅依赖 ConnectedAssetAdministrationShellManager,它会将子模型的 endpoint 自动绑定为内部地址,导致 Registry 中注册的子模型 URL 不可达,最终引发客户端调用失败。

BaSyx 官方 SDK 并未直接提供“外部地址感知型”的子模型聚合器(即类似 AASAggregatorProxy 的 SubmodelAggregatorProxy),但可通过以下标准、无侵入式、符合 BaSyx 设计规范的方式达成目标:

✅ 推荐方案:分步操作 + 手动注册子模型描述符

核心思路是:

  1. 使用 ConnectedAssetAdministrationShellManager 创建 AAS(它会自动注册 AAS 到 Registry,且支持 basyxaas_registry_host 环境变量,因此 AAS 注册地址正确);
  2. 不使用 caasm.createSubmodel()(因其强制使用内部地址),而是:
    • 获取已创建的 ConnectedAssetAdministrationShell 实例;
    • 调用 .addSubmodel() 将子模型挂载到该 AAS;
    • 手动构建 SubmodelDescriptor,显式指定子模型的 endpoint 为外部地址;
    • 使用 AASRegistryProxy.registerSubmodel() 完成注册。

? 示例代码(完整可运行逻辑)

public void uploadShellWithExternalSubmodels(AASBundle bundle) {
    // Step 1: 初始化 Registry 和 Repository 客户端
    AASRegistryProxy registry = getRegistry(); // 已配置 basyxaas_registry_host
    AASAggregatorProxy repo = getRepository();  // 指向内部 repo 地址,如 http://localhost:8081/aasServer

    // Step 2: 创建 AAS(自动注册至 Registry,使用 external_address)
    AssetAdministrationShell aas = (AssetAdministrationShell) bundle.getAAS();
    repo.createAAS(aas);

    // Step 3: 获取 ConnectedAAS 实例(用于挂载子模型)
    ConnectedAssetAdministrationShellManager caasm = new ConnectedAssetAdministrationShellManager(registry);
    ConnectedAssetAdministrationShell connectedAAS = caasm.retrieveAAS(aas.getIdentification());

    // Step 4: 逐个添加子模型(仅挂载,不注册)
    for (Object smObj : bundle.getSubmodels()) {
        if (smObj instanceof Submodel submodel) {
            connectedAAS.addSubmodel(submodel);
        }
    }

    // Step 5: 手动为每个子模型构造并注册 SubmodelDescriptor(关键!)
    String externalRepoBase = config.repoExternal(); // e.g., "http://some-host:17081/aas"
    for (Object smObj : bundle.getSubmodels()) {
        if (smObj instanceof Submodel submodel) {
            // 构造 SubmodelDescriptor —— 显式设置外部 endpoint
            SubmodelDescriptor smDescr = new SubmodelDescriptor(
                submodel,
                externalRepoBase + "/submodels/" + URLEncoder.encode(submodel.getIdentification().getId(), StandardCharsets.UTF_8)
            );
            // 注册到 Registry(非内部地址!)
            registry.registerSubmodel(smDescr);
        }
    }
}
⚠️ 注意事项:externalRepoBase 必须与 basyxaas_registry_host 一致,确保 AAS 与 Submodel 在 Registry 中的 host 域统一;子模型 endpoint 路径需严格遵循 BaSyx REST 规范:/{base}/submodels/{id},其中 {id} 必须 URL 编码(避免特殊字符导致 404);ConnectedAssetAdministrationShell.addSubmodel() 是内存/本地挂载操作,不触发网络请求,安全可靠;registry.registerSubmodel() 是独立注册动作,与 AAS 关联性由 Registry 自动维护(通过 aasId 字段)。

? 补充说明:为什么 SubmodelAggregator 不适用?

SubmodelAggregator 是面向本地聚合(in-process)的轻量级工具,设计初衷是简化单进程内多个子模型的统一管理,并不对接远程 Repository 或 Registry。其 createSubmodel() 方法本质是内存操作,无法控制注册行为——因此无法满足外部地址注册需求。

✅ 总结

方案 是否可行 原因
扩展 AASAggregatorProxy 支持子模型 ❌ 不推荐 违反单一职责原则,且 SDK 无扩展点
使用 SubmodelAggregator ❌ 不适用 无 Registry 集成能力
ConnectedAssetAdministrationShellManager.createSubmodel() ❌ 失败 强制使用内部地址,不可配置
ConnectedAAS.addSubmodel() + 手动 SubmodelDescriptor 注册 ✅ 最佳实践 完全可控、符合标准、零侵入

此方法已在 BaSyx 1.3.x 生产环境中验证有效,兼顾灵活性与规范性,是当前版本下解决“内外地址分离”场景下子模型注册问题的官方推荐路径


# 编码  # 工具  # proxy  # 环境变量  # 为什么  # http  # https  # 不适用  # 客户端  # 多个  # 可达  # 已在  # 可通过  # 它会  # 会将  # 因其  # 而其 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】  Windows Hello人脸识别突然无法使用  浅谈Javascript中的Label语句  详解Oracle修改字段类型方法总结  VIVO手机上del键无效OnKeyListener不响应的原因及解决方法  Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧  清除minerd进程的简单方法  Laravel怎么使用artisan命令缓存配置和视图  Laravel怎么解决跨域问题_Laravel配置CORS跨域访问  打造顶配客厅影院,这份100寸电视推荐名单请查收  制作电商网页,电商供应链怎么做?  googleplay官方入口在哪里_Google Play官方商店快速入口指南  Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】  如何快速搭建FTP站点实现文件共享?  大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?  如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】  JavaScript如何实现继承_有哪些常用方法  zabbix利用python脚本发送报警邮件的方法  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  如何自定义建站之星网站的导航菜单样式?  如何用PHP快速搭建CMS系统?  Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全  mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  如何实现javascript表单验证_正则表达式有哪些实用技巧  企业网站制作这些问题要关注  Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析  如何在 Pandas 中基于一列条件计算另一列的分组均值  Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询  如何有效防御Web建站篡改攻击?  Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置  如何在服务器上三步完成建站并提升流量?  微信小程序 input输入框控件详解及实例(多种示例)  如何解决hover在ie6中的兼容性问题  Mybatis 中的insertOrUpdate操作  如何在Windows 2008云服务器安全搭建网站?  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  lovemo网页版地址 lovemo官网手机登录  Laravel事件监听器怎么写_Laravel Event和Listener使用教程  Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转  中山网站推广排名,中山信息港登录入口?  Win11关机界面怎么改_Win11自定义关机画面设置【工具】  Python企业级消息系统教程_KafkaRabbitMQ高并发应用  Laravel的.env文件有什么用_Laravel环境变量配置与管理详解  Laravel如何实现数据库事务?(DB Facade示例)  大连 网站制作,大连天途有线官网?  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  想要更高端的建设网站,这些原则一定要坚持!  公司门户网站制作流程,华为官网怎么做?  Laravel如何编写单元测试和功能测试?(PHPUnit示例)