跳到主要内容

Browse

browse(String nodeId, Enums.NodeClass filter) — 列出指定节点的直接子节点 (一层).

前置阅读 / 配套

签名

public List<Reference> browse(String nodeId);
public List<Reference> browse(String nodeId, Enums.NodeClass filter);

public List<List<Reference>> browseMany(List<String> nodeIds, Enums.NodeClass filter);

Reference 字段

方法返回说明
getNodeId()String子节点 NodeId
getBrowseName()String浏览名 (含 NamespaceIndex 前缀, 如 2:Temperature)
getDisplayName()String显示名
getNodeClass()Enums.NodeClass子节点类别
toNode(OpcUaSession)OpcUaNode转为可操作的 OpcUaNode

例子

// 列出 Boiler1 下所有子节点
List<Reference> children = ua.browse("ns=2;s=Boiler1");
for (Reference c : children) {
System.out.printf(" %s %s -> %s%n",
c.getNodeClass(), c.getBrowseName(), c.getNodeId());
}

// 只看 Variable 类型
List<Reference> vars = ua.browse("ns=2;s=Boiler1", Enums.NodeClass.Variable);

// 只看 Method
List<Reference> methods = ua.browse("ns=2;s=Calculator", Enums.NodeClass.Method);

批量浏览 (browseMany)

如果同时要浏览多个节点 (例如 GUI 初次展开树), 用 browseMany 一次 RPC:

List<String> roots = Arrays.asList(
"i=85" /* Objects */,
"i=86" /* Types */);
List<List<Reference>> results = ua.browseMany(roots, Enums.NodeClass.Unspecified);
for (int i = 0; i < roots.size(); i++) {
System.out.println(roots.get(i) + ":");
for (Reference c : results.get(i)) {
System.out.println(" " + c.getBrowseName());
}
}

如果某个节点浏览失败 (NodeId 错), 对应槽位返回空列表, 不抛异常.


NodeClass filter

包含
Unspecified (0)全部
Object (1)仅 Object
Variable (2)仅 Variable
Method (4)仅 Method

Java 不支持按位或运算 enum, 想要"Object + Variable"组合请分两次 browse 后合并, 或循环过滤结果.


异常

OpcUaException(BadNodeIdUnknown) / OpcUaException(BadCommunicationError) 等. transport 失败抛, 单个子节点失败不抛.

大节点的分页 (ContinuationPoint)

如果一个节点有 1000+ 个子节点, 单次 browse 服务端可能截断. 此时 browse 只返回第一页, 续点被丢弃.

要看全部, 用 browseWithPaging + browseNext, 或直接 browseAll:

List<Reference> all = ua.browseAll("ns=2;s=BigFolder");  // 自动分页
System.out.println("Total " + all.size() + " children");

性能

  • 单次 browse: ~5-15 ms (网络往返 + 服务端遍历)
  • browseMany 批量: 总耗时 ~ 单次 (省 N-1 次往返)
  • 1000+ 子节点会分页, 用 browseAll 或手动 browseNext

下一步