用 OPC UA C# WinForm 的单节点订阅方法
调用 OPC UA C# WinForm 的单节点订阅方法
SingleNodeIdDatasSubscription
方法用于订阅单个 OPC UA 节点的数据变化。以下是调用这个方法的完整示例:
基本调用示例
// 1. 定义订阅的关键字(必须唯一)
string subscriptionKey = "MySingleSubscription_Temperature";// 2. 准备要订阅的节点ID
string nodeId = "ns=2;s=Device1/Temperature";// 3. 定义回调方法
Action<string, MonitoredItem, MonitoredItemNotificationEventArgs> callback = (key, monitoredItem, args) =>
{// 处理订阅到的数据var notification = args.NotificationValue as MonitoredItemNotification;if (notification != null){// 获取节点值var value = notification.Value.Value;// 在UI线程上更新界面(如果是WinForm应用)this.Invoke((MethodInvoker)delegate {// 显示接收到的数据textBoxLog.AppendText($"[单节点订阅] Key: {key}, NodeId: {monitoredItem.StartNodeId}, " +$"Value: {value}, Timestamp: {notification.Value.SourceTimestamp}\r\n");// 也可以更新特定的控件,如温度显示lblTemperature.Text = $"{value} °C";});}
};// 4. 调用单节点订阅方法
SingleNodeIdDatasSubscription(subscriptionKey, nodeId, callback);
实际应用中的增强用法
1. 封装订阅方法
public void SubscribeTemperature()
{string key = "TemperatureSubscription_001";string nodeId = "ns=2;s=Device1/Temperature";SingleNodeIdDatasSubscription(key, nodeId, (k, item, args) => {var notification = args.NotificationValue as MonitoredItemNotification;if (notification != null){this.Invoke((MethodInvoker)delegate {lblTemperature.Text = $"{notification.Value.Value} °C";chartTemperature.AddDataPoint(DateTime.Now, Convert.ToDouble(notification.Value.Value));});}});
}
2. 带错误处理的订阅
public bool TrySubscribeSingleNode(string key, string nodeId, out string errorMessage)
{errorMessage = string.Empty;if (!ConnectStatus){errorMessage = "OPC UA客户端未连接";return false;}try{SingleNodeIdDatasSubscription(key, nodeId, (k, item, args) => {// 回调处理逻辑});return true;}catch (Exception ex){errorMessage = $"订阅节点 {nodeId} 失败: {ex.Message}";return false;}
}// 调用示例
if (!TrySubscribeSingleNode("PressureSub_001", "ns=2;s=Device1/Pressure", out var error))
{MessageBox.Show(error);
}
3. 取消订阅
public void UnsubscribeSingleNode(string key)
{if (ConnectStatus){try{opcUaClient.RemoveSubscription(key);}catch (Exception ex){string str = $"取消订阅 {key} 失败";ClientUtils.HandleException(str, ex);}}
}// 调用示例
UnsubscribeSingleNode("MySingleSubscription_Temperature");
回调方法的更多处理示例
// 更复杂的回调处理
Action<string, MonitoredItem, MonitoredItemNotificationEventArgs> advancedCallback = (key, monitoredItem, args) =>
{var notification = args.NotificationValue as MonitoredItemNotification;if (notification == null) return;var value = notification.Value.Value;var statusCode = notification.Value.StatusCode;var timestamp = notification.Value.SourceTimestamp;this.Invoke((MethodInvoker)delegate {// 记录原始数据textBoxRawData.AppendText($"{DateTime.Now}: {key} - {value}\r\n");// 根据节点ID进行不同处理if (monitoredItem.StartNodeId.ToString().Contains("Temperature")){double temp = Convert.ToDouble(value);UpdateTemperatureGauge(temp);CheckTemperatureAlarm(temp);}else if (monitoredItem.StartNodeId.ToString().Contains("Pressure")){UpdatePressureChart(Convert.ToDouble(value), timestamp);}});
};
调用单节点订阅方法时,关键是要确保:
- 订阅键(key)的唯一性
- 节点ID(nodeId)的正确性
- 回调方法正确处理数据并在需要时跨线程更新UI
- 适当的错误处理和资源清理