Browse
Browse(string nodeId, NodeClass filter = Unspecified) — 列出指定节点的直接子节点 (一层).
前置阅读 / 配套
- 大节点分页请用 BrowseWithPaging + BrowseNext.
- 路径式批量解析请用 TranslateBrowsePaths.
签名
public IReadOnlyList<OpcUaReference> Browse(
string nodeId,
NodeClass filter = NodeClass.Unspecified);
public IReadOnlyList<IReadOnlyList<OpcUaReference>> BrowseMany(
IReadOnlyList<string> nodeIds,
NodeClass filter = NodeClass.Unspecified);
OpcUaReference 字段
| 字段 | 类型 | 说明 |
|---|---|---|
NodeId | string | 子节点 NodeId |
BrowseName | string | 浏览名 (含 NamespaceIndex 前缀, 如 2:Temperature) |
DisplayName | string | 显示名 |
NodeClass | NodeClass | 子节点类别 |
例子
// 列出 Boiler1 下所有子节点
var children = ua.Browse("ns=2;s=Boiler1");
foreach (var c in children)
Console.WriteLine($" {c.NodeClass} {c.BrowseName} -> {c.NodeId}");
// 只看 Variable 类型
var vars = ua.Browse("ns=2;s=Boiler1", filter: NodeClass.Variable);
// 只看 Method
var methods = ua.Browse("ns=2;s=Calculator", filter: NodeClass.Method);
批量浏览 (BrowseMany)
如果同时要浏览多个节点 (例如 GUI 初次展开树), 用 BrowseMany 一次 RPC:
var roots = new[] { "i=85" /* Objects */, "i=86" /* Types */ };
var results = ua.BrowseMany(roots);
for (int i = 0; i < roots.Length; i++)
{
Console.WriteLine($"{roots[i]}:");
foreach (var c in results[i])
Console.WriteLine($" {c.BrowseName}");
}
如果某个节点浏览失败 (NodeId 错), 对应槽位返回空列表, 不抛异常.
NodeClass filter
| 值 | 包含 |
|---|---|
Unspecified (0) | 全部 |
Object (1) | 仅 Object |
Variable (2) | 仅 Variable |
Method (4) | 仅 Method |
Object | Variable | 组合 (按位或) |
异常
OpcUaException(BadNodeIdUnknown) / OpcUaException(BadCommunicationError) 等. transport 失败抛, 单个子节点失败不抛.
大节点的分页 (ContinuationPoint)
如果一个节点有 1000+ 个子节点, 单次 Browse 服务端可能截断. 此时 Browse 只返回第一页.
要看全部, 用 BrowseWithPaging + BrowseNext:
var page = ua.BrowseWithPaging("ns=2;s=BigFolder");
var allRefs = new List<OpcUaReference>(page.References);
while (page.ContinuationPoint != null)
{
page = ua.BrowseNext(page.ContinuationPoint);
allRefs.AddRange(page.References);
}
性能
- 单次 Browse: ~5-15 ms (网络往返 + 服务端遍历)
- BrowseMany 批量: 总耗时 ~ 单次 (省 N-1 次往返)
- 1000+ 子节点会分页, 加 BrowseNext 处理