RegisterNodes / UnregisterNodes
registerNodes 服务把客户端常用的 NodeId 注册到服务端, 服务端返回临时高效 NodeId (生命周期 = Session). 后续 read / write / MonitoredItem 用这个临时 ID 比原始 NodeId 快得多 (服务端跳过完整 NodeId 解析).
适用判断
- 单次脚本 → 不需要
- 长期运行高频访问相同节点 → 强烈推荐
- 大规模 SCADA 1000+ Tag 持续监控 → 必须
签名
public List<String> registerNodes(List<String> nodeIds);
public Enums.StatusCode unregisterNodes(List<String> registeredNodeIds);
用法
import java.util.Arrays;
import java.util.List;
// 1. 应用启动时注册
List<String> orig = Arrays.asList(
"ns=2;s=Plant.Line1.Sensor.Temperature",
"ns=2;s=Plant.Line1.Sensor.Pressure",
"ns=2;s=Plant.Line1.Sensor.FlowRate");
List<String> temp = ua.registerNodes(orig);
// temp 现在是服务端给的临时 ID, 类似 "i=99001", "i=99002", "i=99003"
// 2. 后续高频访问用临时 ID (快得多)
for (int i = 0; i < 10000; i++) {
try (OpcUaDataValue dv = ua.read(temp.get(0))) {
// 比 ua.read("ns=2;s=Plant.Line1.Sensor.Temperature") 快
}
}
// 3. 应用退出前释放
ua.unregisterNodes(temp);
何时用
| 场景 | 必要性 |
|---|---|
| 单次脚本, 100 个节点 | 低 (省的开销可忽略) |
| 长期运行, 高频访问相同节点 | 高 (省时显著) |
| 大规模 SCADA, 1000+ Tag 持续监控 | 必须 |
性能数据
服务端 NodeId 解析的耗时取决于实现:
- 数字 NodeId (
i=2258) 通常 O(1) 哈希查找 — registerNodes 收益小 - 字符串 NodeId 长路径 (
ns=2;s=Plant.Line1.Sensor.Temperature) — 服务端可能 O(n) 字符串解析, registerNodes 收益大 (典型 30-50% 加速)
注意
- 注册的临时 ID 只在当前 Session 有效, disconnect 后失效
- Session 重连后 (transferSubscriptions) 临时 ID 通常仍有效, 但保险起见重新 register
- 不释放的临时 ID 会随 Session 关闭自动 GC, 但显式
unregisterNodes是好习惯
临时 ID 是不透明的
不要解析 / 修改临时 ID 字符串. 把它当成一个 opaque token 用就行.