关于OPC UA Helper 命名空间中的OpcUaClient 类中的订阅函数的更改
原函数是opcUaClient.MonitorValue("ns=4;s=MAIN.d", new Action<double, Action>(MonitorTestValueFloat));
由于订阅函的的回调函的类型是
public void MonitorValue<T>(string tag, Action<T, Action> callback);
所以返回的函数参数中只有数值,所以在实际应用中是不够的,另外多个订阅就要加多个回调函数处理。为此需要更改为
private void MonitorTestValueFloat(object clientHandle, DataValue value)
操作步骤如下:
先继承OpcUaHelper.OpcUaClient 后添加订阅方法 具体代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Opc.Ua;
using Opc.Ua.Client;
namespace 组态
{
/// <summary>
/// 值变化委托函数
/// </summary>
/// <param name="clientHandle">客户处理事件</param>
/// <param name="value">变化的值</param>
public delegate void valueChanged(object clientHandle, DataValue value);
class MyOpcUa:OpcUaHelper.OpcUaClient
{
/// <summary>
/// OPCUA服务器订阅
/// </summary>
private Subscription m_Subscription;
/// <summary>
/// 添加处理函数
/// </summary>
public void addNotificationHandle(int publishingInterval)
{
try
{
Opc.Ua.Client.Subscription innerSubscription = new Opc.Ua.Client.Subscription(this.Session.DefaultSubscription);
innerSubscription.DisplayName = "My Subscription Name";
innerSubscription.PublishingEnabled = true;
innerSubscription.PublishingInterval = publishingInterval; // in milliseconds.
innerSubscription.KeepAliveCount = 10; // 10*UaRefreshRate = 5s if UaRefreshRate = 500
innerSubscription.LifetimeCount = 100; // UaRefreshRate*100 = 50s if UaRefreshRate = 500;
innerSubscription.MaxNotificationsPerPublish = 100;
//将订阅与会话关联起来
this.Session.AddSubscription(innerSubscription);
// Call the server and create the subscription.
//调用服务器并创建订阅。
innerSubscription.Create();
// At this point the subscription is sending publish requests at the keep alive rate.
// Use the Notification event the session to receive updates when a publish completes.
//此时,订阅将以保持活跃的速率发送发布请求。
//使用通知事件会话在发布完成时接收更新。
this.Session.Notification += new NotificationEventHandler(Session_Notification);
m_Subscription = innerSubscription;
//m_Subscription.Session = m_Session;
//newSubscription.innerSubscription = innerSubscription;
}
catch (Exception e)
{
throw e;
}
this.Session.Notification += Session_Notification;
}
/// <summary>
/// 添加订阅函数
/// </summary>
/// <param name="variableNodeId">节点ID</param>
/// <param name="clientHandle">客户端对象</param>
/// <param name="callback">回调函数</param>
/// <param name="samplingRate">采样时间.</param>
/// <param name="serverHandle">服务处理</param>
public void AddDataMonitoredItem(NodeId variableNodeId, object clientHandle, valueChanged callback, uint samplingRate, out object serverHandle)
{
serverHandle = null;
try
{
if (m_Subscription==null)
{
m_Subscription = new Subscription();
//m_Subscription.Session = m_Session;
}
MonitoredItem monitoredItem = (m_Subscription.DefaultItem);
ClientMonitoredItemData clientData = new ClientMonitoredItemData();
clientData.callback = callback;
clientData.clientHandle = clientHandle;
// Monitored item settings:
monitoredItem.StartNodeId = variableNodeId;
monitoredItem.AttributeId = Attributes.Value;
monitoredItem.MonitoringMode = MonitoringMode.Reporting;
monitoredItem.SamplingInterval = (int)samplingRate; // Affects the read cycle between UA Server and data source
monitoredItem.QueueSize = 1;
monitoredItem.DiscardOldest = false;
monitoredItem.Handle = clientData;
// Add item to subscription.
m_Subscription.AddItem(monitoredItem);
// Call the server and apply any changes to the state of the subscription or monitored items.
m_Subscription.ApplyChanges();
// Check result of add.
if (monitoredItem.Status.Error != null && StatusCode.IsBad(monitoredItem.Status.Error.StatusCode))
{
throw ServiceResultException.Create(
monitoredItem.Status.Error.StatusCode.Code,
"Creation of data monitored item failed");
}
serverHandle = monitoredItem;
}
catch (Exception e)
{
throw e;
}
}
/// <summary>
/// 当服务器发布数据时,响应从到达时,就会执行函数。
/// </summary>
/// <param name="session">The target of the event.</param>
/// <param name="e">The <see cref="Opc.Ua.Client.NotifacationEventArgs"/>Instance containing the event data.</param>
private void Session_Notification(Session session, NotificationEventArgs e)
{
NotificationMessage message = e.NotificationMessage;
// Check for keep alive.
if (message.NotificationData.Count == 0)
{
return;
}
// Get the data changes (oldest to newest).
foreach (MonitoredItemNotification datachange in message.GetDataChanges(false))
{
// Lookup the monitored item.
MonitoredItem monitoredItem = e.Subscription.FindItemByClientHandle(datachange.ClientHandle);
if (monitoredItem == null)
{
continue;
}
ClientMonitoredItemData clientData = monitoredItem.Handle as ClientMonitoredItemData;
clientData.callback(clientData.clientHandle, datachange.Value);
}
}
}
/// <summary>
/// 客户端监控项数据
/// </summary>
public class ClientMonitoredItemData
{
/// <summary>
/// 客户端处理对象
/// </summary>
public object clientHandle = null;
/// <summary>
/// 变化值
/// </summary>
public valueChanged callback = null;
}
}
调用方法
MyOpcUa opcUaClient = new MyOpcUa();
opcUaClient.ConnectServer("opc.tcp://localhost:4840");
opcUaClient.addNotificationHandle(1000);
object sobj = null;
//opcUaClient.MonitorValue("ns=4;s=MAIN.d", new Action<double, Action>(MonitorTestValueFloat));
opcUaClient.AddDataMonitoredItem("ns=4;s=MAIN.d", null, MonitorTestValueFloat, 1000, out sobj);
//回调处理函数
//clientHandle:用户对象,
//value:数据值
private void MonitorTestValueFloat(object clientHandle, DataValue value)
{
object objv = value.Value;
}
关于OPC UA Helper 命名空间中的OpcUaClient 类中的订阅函数的更改的更多相关文章
- Oracle数据库中调用Java类开发存储过程、函数的方法
Oracle数据库中调用Java类开发存储过程.函数的方法 时间:2014年12月24日 浏览:5538次 oracle数据库的开发非常灵活,不仅支持最基本的SQL,而且还提供了独有的PL/SQL, ...
- 实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法
实现Square类,让其继承自Rectangle类,并在Square类增添新属性和方法,在2的基础上,在Square类中重写Rectangle类中的初始化和打印方法 #import <Found ...
- 尚硅谷面试第一季-11MyBatis中当实体类中的属性名和表中的字段名不一样怎么办
问题: MyBatis中当实体类中的属性名和表中的字段名不一样 ,怎么办 ? 解决方案: 1.写sql语句时起别名 <!-- id属性:必须是接口中方法的方法名 resultType属性:必须是 ...
- 转载:C++中两个类中互相包含对方对象的指针问题
原文链接:http://www.cnblogs.com/hanxi/archive/2012/07/25/2608068.html 前几天很不爽,因为C++中两个类中互相包含对方对象的指针编译时提示某 ...
- 【记录】mybatis中获取常量类中数据
部分转载,已注明来源: 1.mybatis中获取常量类中数据 <update id="refuseDebt"> UPDATE dt_debt a SET ...
- cc31a_demo--CppPrimer_静态成员与继承-在派生类中访问基类中的static成员的方法
//*基类中的static成员,在整个继承层次中只有一个实例 //*在派生类中访问基类中的static成员的方法 //1.基类名::成员名 //2.子类名::成员名 //3.对象.成员名 //4.指针 ...
- c++中可以对类中私有成员中的静态变量初始化吗?
转载http://www.cnblogs.com/carbs/archive/2012/04/04/2431992.html 问题:我看的书上写的对私有部分的访问可以是公共部分的成员函数,也可以是友员 ...
- java面向对象中的String类中12种常用的方法
1.字符串与字符数组的转换 字符串可以使用toCharArray()方法变成一个字符数组,也可以使用String类的构造方法把一个字符数组变成一个字符串. public class StringAPI ...
- Python中从B类中调用A类的方法。
好久没上了,Python还在学--最近进度有点慢... 下面代码记录了一个不太好理解的点,自己写了个小例子,总算是理顺了. B类想要调用A类,自己在网上看了一下其他人的回复:创建A类的实例,直接调用这 ...
随机推荐
- Java经典编程题50道之十七
猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个:第二天早上又将剩下的桃子吃掉一半,而且又多吃了一个.以后每天早上都吃了前一天剩下的一半零一个.到第10天早上想再吃时,就只 ...
- java3 - 流程控制
一.Java 有三种主要的循环结构: 需求:分别使用三种循环将 1 到 100 的整数输出到控制台. 1.for 循环 for(初始化语句; 布尔表达式语句; 更新语句) { //循环体内容 } 示列 ...
- ubuntu上lamp环境搭建
首先,介绍个彻底删除linux已经安装的软件的方法. sudo apt-get purge mysql-server mysql-client mysql-common mysql-server-5. ...
- 如何使用 libqr 库生成二维码?
使用 libqr 库只需 4 步即可生成二维码 1.初始化 QRCode 结构体 QRCode *qrInit(int version, int mode, int eclevel, int mask ...
- Python接口自动化测试 HTTP协议
一.HTTP协议简述 二.URL 三.请求 四.响应 五.消息报头 六.常见问题
- C语言老司机学Python (一)
Python 版本:3.6.4 参考网上教程:http://www.runoob.com/python3/python3-basic-syntax.html 开始了啊. 干咱们这行的老规矩,学新语言的 ...
- python file文件操作--内置对象open
说明: 1. 函数功能打开一个文件,返回一个文件读写对象,然后可以对文件进行相应读写操作. 2. file参数表示的需要打开文件的相对路径(当前工作目录)或者一个绝对路径,当传入路径不存在此文件会报错 ...
- win10 , JAVA安装 环境搭建
一.关于下载地址及方式: 1.百度搜索JDK,进入下载官网,具体网址如下: click me!!! 2.根据你电脑的不同系统选择对应的下载,当然首先你要点击Accept License Agreeme ...
- linux dns搭建
DNS:域名解析(Domain Nmae System)正向解析:根据主机名称(域名)查找其对应的ip地址,这是最基本,最常用的功能反向解析:根据ip地址查找其对应的主机名称(域名),反垃圾邮件/安全 ...
- java.sql.SQLException: Access denied for user 'sa'@'localhost' (using password: NO)
1.错误描述 INFO:2015-05-01 16:53:29[main] - HHH000228: Running hbm2ddl schema update INFO:2015-05-01 16: ...