C#开发OPC UA客户端订阅节点后无打印输出问题求助
OPC UA客户端代码问题修复说明
存在的核心问题
- 程序执行完订阅逻辑后立即释放OpcClient对象并退出,没有阻塞逻辑保活客户端进程,数据变化回调无法触发
- 订阅相关逻辑错误放在finally块中,无论服务端连接失败时仍会执行无效的订阅操作,触发异常
- Console.WriteLine格式化语法错误,无法输出内容格式不符合预期
- Browse方法为非静态方法,无法在静态的Main方法中调用(若后续需要浏览节点功能需要调整)
修复后完整代码
using System; using Opc.UaFx; using Opc.UaFx.Client; using System.Collections.Generic; namespace Client { public class Program { static void Main(string[] args) { using (var client = new OpcClient("opc.tcp://127.0.0.1:62541/")) { try { client.Connect(); Console.WriteLine("服务端连接成功"); } catch { Console.WriteLine("无法连接到OPC UA服务端"); return; } // 节点列表 string[] nodeIds = { "ns=1;s=[Simulatore OPC Server]ST20543", "ns=1;s=[Simulatore OPC Server]ST1", "ns=1;s=[Simulatore OPC Server]ST2", "ns=1;s=[Simulatore OPC Server]ST3", "ns=1;s=[Simulatore OPC Server]ST4", "ns=1;s=[Simulatore OPC Server]ST5", "ns=1;s=[Simulatore OPC Server]ST6", "ns=1;s=[Simulatore OPC Server]ST7", "ns=1;s=[Simulatore OPC Server]ST8", "ns=1;s=[Simulatore OPC Server]ST9", "ns=1;s=[Simulatore OPC Server]ST10" }; OpcSubscription subscription = client.SubscribeNodes(); for (int index = 0; index < nodeIds.Length; index++) { var item = new OpcMonitoredItem(nodeIds[index], OpcAttribute.Value); item.DataChangeReceived += HandleDataChanged; item.Tag = index; item.SamplingInterval = 200; subscription.AddMonitoredItem(item); Console.WriteLine($"{{\"Timestamp\":\"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffffK")}\",\"消息\":\"已添加订阅节点: {nodeIds[index]}\"}}"); } subscription.ApplyChanges(); Console.WriteLine("订阅已生效,按q键退出程序"); // 阻塞进程保活 while(Console.ReadKey(true).Key != ConsoleKey.Q) { // 空循环等待用户按q退出 } } } // 节点浏览方法 调整为静态方法 private static void Browse(OpcNodeInfo node, int level = 0) { Console.WriteLine("{0}{1}({2})", new string('.', level * 4), node.Attribute(OpcAttribute.DisplayName).Value, node.NodeId); level++; foreach (var childNode in node.Children()) Browse(childNode, level); } // 数据变化回调 private static void HandleDataChanged(object sender, OpcDataChangeReceivedEventArgs e) { OpcMonitoredItem item = (OpcMonitoredItem)sender; // 修正格式化写法 Console.WriteLine($"{{\"Timestamp\":\"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffffK")}\",\"内容\":\"Data Change from NodeId '{item.NodeId}': {e.Item.Value}\"}}"); } } }
额外注意事项
- 确认服务端地址
opc.tcp://127.0.0.1:62541/和节点ID配置正确,若服务端开启了身份验证,需要在连接前配置client.Security.UserIdentity传入用户名密码 - 若节点ID拼写错误,订阅会无法收到数据,可调用Browse方法遍历服务端节点确认节点ID正确性
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

