跳到主要内容

Node — darra::opcua::Node

NodeNodeCollection 索引器返回的包装对象, 表示远程一个节点. Lazy Load — 只有访问方法才触发 RPC.

前置阅读

公共方法 (访问器)

类别属性类型访问说明
标识 (无 RPC)NodeId()std::string const&R节点 ID 字符串
数据 (触发 RPC)Value()DataValueR当前值 — 触发 Read(Value)
DisplayName()std::stringR显示名 — 触发 Read(DisplayName)
BrowseName()std::stringR浏览名 — 触发 Read(BrowseName)
Description()std::stringR描述 — 触发 Read(Description)
GetNodeClass()NodeClassR节点类别 — 触发 Read(NodeClass)
IsReadable()boolRAccessLevel bit 0 — 触发 Read(AccessLevel)
IsWritable()boolRAccessLevel bit 1 — 触发 Read(AccessLevel)
OwnerOwner()Session&R所属 Session 引用

索引器

索引返回说明
node[std::string const& browse_name]Node子节点 (按 BrowseName 浏览)

公共方法

方法说明
ReadAttribute(attr)读指定 Attribute, 返回 DataValue
Write(variant)写 Value 属性
WriteAttribute(attr, variant)写指定 Attribute
Children(filter = Unspecified)浏览子节点, 返回 std::vector<Reference>
Resolve(path)按 BrowsePath 深层解析
Call(parent_obj_id, inputs)调用本节点为方法 (本节点须是 Method 类型)

例子

// 1. 拿节点 (无 RPC)
auto temp = s.Nodes()["ns=2;s=Temperature"];

// 2. 读基本信息 (各 1 次 RPC)
std::cout << "NodeId = " << temp.NodeId() << "\n";
std::cout << "DisplayName = " << temp.DisplayName() << "\n";
std::cout << "NodeClass = " << static_cast<int>(temp.GetNodeClass()) << "\n";

// 3. 读值
auto dv = temp.Value();
double t = 0; dv.Value().TryGetDouble(t);
std::cout << "Value = " << t << " degC ft=" << dv.SourceTimestamp() << "\n";

// 4. 写
Variant v; v.SetDouble(25.5);
temp.Write(v);

// 5. 浏览子节点
for (auto const& child : temp.Children()) {
std::cout << " " << child.browse_name << " -> " << child.node_id << "\n";
}

// 6. 链式访问 (Server.ServerStatus.CurrentTime)
auto time = s.Nodes().Server()["ServerStatus"]["CurrentTime"].Value();
std::cout << "Server time ft=" << time.Value().AsFileTime() << "\n";

注意事项

  • 所有触发 RPC 的方法都是"读一次返回一次", 不缓存. 想缓存自己存变量
  • 链式访问 a["b"]["c"] 每段都是一次 Browse RPC, 总计 N 次
  • DataValue 是栈对象, 离开作用域自动析构释放 native 内存
  • 跨线程使用 Node 安全 (它只持有 NodeId 字符串 + Session 指针), 但 DataValue 不要跨线程

与 Resolve 的对比

// 方式 A: 链式索引器 - 4 次 RPC
auto time = s.Nodes().Server()["ServerStatus"]["CurrentTime"].Value();
// 1 次 2 次 3 次 4 次 Read

// 方式 B: 路径解析 - 2 次 RPC
auto node = s.Resolve("/Objects/Server/ServerStatus/CurrentTime"); // 1 次
auto time = node.Value(); // 1 次

// 方式 C: 直接 NodeId - 1 次 RPC
auto time = s.Read("i=2258");

如果路径已知 → 方式 C; 探索式开发 → 方式 A.

下一步