跳到主要内容

register_nodes / unregister_nodes

register_nodes 服务把客户端常用的 NodeId 注册到服务端, 服务端返回临时高效 NodeId (生命周期 = Session). 后续 read / write / MonitoredItem 用这个临时 ID 比原始 NodeId 快得多 (服务端跳过完整 NodeId 解析).

适用判断
  • 单次脚本 → 不需要
  • 长期运行高频访问相同节点 → 强烈推荐
  • 大规模 SCADA 1000+ Tag 持续监控 → 必须

签名

def register_nodes(self, node_ids: List[str]) -> List[Optional[str]]: ...
def unregister_nodes(self, registered_node_ids: List[str]) -> StatusCode: ...

返回的临时 NodeId 列表与入参顺序对应, 失败槽位为 None.


用法

# 1. 应用启动时注册
orig = [
"ns=2;s=Plant.Line1.Sensor.Temperature",
"ns=2;s=Plant.Line1.Sensor.Pressure",
"ns=2;s=Plant.Line1.Sensor.FlowRate",
]
temp = ua.register_nodes(orig)
# temp 现在是服务端给的临时 ID, 类似 ["i=99001", "i=99002", "i=99003"]

# 2. 后续高频访问用临时 ID (快得多)
for _ in range(10000):
with ua.read(temp[0]) as dv:
# 比 read("ns=2;s=Plant.Line1.Sensor.Temperature") 快
pass

# 3. 应用退出前释放
ua.unregister_nodes([t for t in temp if t])

何时用

场景必要性
单次脚本, 100 个节点低 (省的开销可忽略)
长期运行, 高频访问相同节点 (省时显著)
大规模 SCADA, 1000+ Tag 持续监控必须

性能数据

服务端 NodeId 解析的耗时取决于实现:

  • 数字 NodeId (i=2258) 通常 O(1) 哈希查找 — register_nodes 收益小
  • 字符串 NodeId 长路径 (ns=2;s=Plant.Line1.Sensor.Temperature) — 服务端可能 O(n) 字符串解析, register_nodes 收益大 (典型 30-50% 加速)

注意

  • 注册的临时 ID 只在当前 Session 有效, disconnect 后失效
  • Session 重连后 (transfer_subscriptions) 临时 ID 通常仍有效, 但保险起见重新 register
  • 不释放的临时 ID 会随 Session 关闭自动 GC, 但显式 unregister 是好习惯

下一步