跳到主要内容

Browse

Browse(string nodeId, NodeClass filter = Unspecified) — 列出指定节点的直接子节点 (一层).

前置阅读 / 配套

签名

public IReadOnlyList<OpcUaReference> Browse(
string nodeId,
NodeClass filter = NodeClass.Unspecified);

public IReadOnlyList<IReadOnlyList<OpcUaReference>> BrowseMany(
IReadOnlyList<string> nodeIds,
NodeClass filter = NodeClass.Unspecified);

OpcUaReference 字段

字段类型说明
NodeIdstring子节点 NodeId
BrowseNamestring浏览名 (含 NamespaceIndex 前缀, 如 2:Temperature)
DisplayNamestring显示名
NodeClassNodeClass子节点类别

例子

// 列出 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 处理

BrowseFiltered — 方向 + 引用类型过滤

BrowseFilteredBrowse 的基础上加 BrowseDirection + referenceTypeId + includeSubtypes + resultMask 过滤 (Part 4 §5.8.2.2 BrowseDescription).

public static IReadOnlyList<OpcUaReference> BrowseFiltered(
this DarraOpcUa session,
string nid,
NodeClass nodeClassFilter = NodeClass.Unspecified,
BrowseDirection direction = BrowseDirection.Forward,
string referenceTypeId = null,
bool includeSubtypes = true,
uint resultMask = 0x3F);

相关结构:

public enum BrowseDirection
{
Forward = 0, // 仅正向 (出引用), 父→子
Inverse = 1, // 仅反向 (入引用), 子→父
Both = 2 // 正反向都返回
}

示例

// 1) 仅看正向 + 仅 HierarchicalReferences (i=33)
var children = ua.BrowseFiltered("ns=2;s=Boiler1",
direction: BrowseDirection.Forward,
referenceTypeId: "i=33",
includeSubtypes: true);

// 2) 反向找父节点 (谁引用我)
var parents = ua.BrowseFiltered("ns=2;s=Tank.Level",
direction: BrowseDirection.Inverse);
foreach (var p in parents) Console.WriteLine($"父: {p.BrowseName}");

// 3) 双向 (Both) — 看节点全部连接关系
var all = ua.BrowseFiltered("ns=2;s=Robot.Joint1", direction: BrowseDirection.Both);

实现说明

  • Stack 提供 DarraUa_Session_BrowseWithFilter 时直调原生
  • 否则 fallback 到现有 Browse + 客户端按 NodeClass 过滤; referenceTypeId / direction / includeSubtypes 在 fallback 模式下无法精确生效, 会打 Warning

BrowseAll — 自动续翻

public static IReadOnlyList<OpcUaReference> BrowseAll(
this DarraOpcUa session, string nodeId,
NodeClass filter = NodeClass.Unspecified, int maxPages = 32);

自动反复调 BrowseNext 直到 ContinuationPoint 为空, 不用业务侧手写循环。

var allRefs = ua.BrowseAll("ns=2;s=BigFolder");
Console.WriteLine($"共 {allRefs.Count} 个子节点");

下一步