如何从OPC UA服务器获取未知组与标签?附代码改造需求
解决方案
不需要额外配置,利用OPC UA标准的**地址空间浏览(Browse)**功能即可实现,现有Opc.Ua.Client命名空间完全支持该操作。核心思路是从服务器的根节点(或指定命名空间节点)开始递归遍历,区分文件夹(对应你说的“组”)和变量(对应“标签”),并输出层级结构。
代码示例
在你现有代码的OPCUAClass中添加浏览节点的递归方法,并在会话初始化完成后调用:
1. 添加浏览方法到OPCUAClass
// 递归浏览服务器节点,输出组(文件夹)和标签(变量) public void BrowseServerNodes(NodeId startingNodeId, int indentLevel = 0) { if (OPCSession == null || !OPCSession.Connected) { Console.WriteLine("会话未连接,无法浏览节点"); return; } // 构建浏览请求配置 var browseDescription = new BrowseDescription { NodeId = startingNodeId, BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences, IncludeSubtypes = true, NodeClassMask = (uint)(NodeClass.Object | NodeClass.Variable), ResultMask = (uint)BrowseResultMask.All }; // 执行浏览请求 BrowseResult browseResult = OPCSession.Browse(null, null, 0, browseDescription); foreach (var reference in browseResult.References) { // 读取节点的显示名称和类型属性 NodeAttributes attributes = OPCSession.ReadNodeAttributes(reference.NodeId, Attributes.DisplayName | Attributes.NodeClass); string displayName = attributes.DisplayName?.Text ?? reference.NodeId.ToString(); NodeClass nodeClass = (NodeClass)attributes.NodeClass; // 层级缩进,优化控制台输出格式 string indent = new string(' ', indentLevel * 2); if (nodeClass == NodeClass.Object) { // 对象节点(文件夹),视为"组" Console.WriteLine($"{indent}[组] {displayName} (NodeId: {reference.NodeId})"); // 递归浏览子节点 BrowseServerNodes(reference.NodeId, indentLevel + 1); } else if (nodeClass == NodeClass.Variable) { // 变量节点,视为"标签" Console.WriteLine($"{indent}[标签] {displayName} (NodeId: {reference.NodeId})"); } } }
2. 在会话初始化后调用浏览方法
修改InitializeOPCUAClient方法,在会话创建成功后添加浏览逻辑:
// 原会话创建代码之后添加: Console.WriteLine("\n=== 服务器节点结构 ==="); // 从OPC UA根节点开始全量浏览 BrowseServerNodes(ObjectIds.RootFolder); // 如果只想浏览指定命名空间的节点(比如你代码中的ns=2),可以先定位到该命名空间的根节点 // 示例:假设命名空间根节点标识符为0,可替换为实际值 // NodeId namespaceRoot = new NodeId(0, OPCNameSpace); // BrowseServerNodes(namespaceRoot);
3. 测试浏览功能(可选修改Main方法)
可以暂时注释掉已知标签的订阅逻辑,先验证浏览功能:
public static void Main(string[] args) { Console.WriteLine("Start"); // 注释已知标签,先测试浏览 // TagList.Add("Value 1", new OPCUAClass.TagClass("Number 1", "FileValue.FileData")); // TagList.Add("Value 2", new OPCUAClass.TagClass("Number 2", "FileValue.FileData2")); myOPCUAServer = new OPCUAClass("127.0.0.1", "8666", new Dictionary<string, OPCUAClass.TagClass>(), true, 1, "2"); }
配置说明
不需要额外配置,只需满足两个前提:
- 客户端已成功与OPC UA服务器建立会话(你的现有代码已实现连接逻辑)。
- 服务器允许地址空间浏览操作(绝大多数OPC UA服务器默认开启该权限,无需额外配置)。
内容的提问来源于stack exchange,提问作者FaceHoof
相关产品推荐
相关产品推荐

